diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 660f92d8f7b92..6a1f9c1a4c78e 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -63,6 +63,8 @@ println!("path exists: {}", path.exists()); */ +#![deny(deprecated_owned_vector)] + use container::Container; use c_str::CString; use clone::Clone; @@ -70,10 +72,11 @@ use fmt; use iter::Iterator; use option::{Option, None, Some}; use str; -use str::{MaybeOwned, OwnedStr, Str, StrSlice, from_utf8_lossy}; -use slice; -use slice::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector}; +use str::{MaybeOwned, Str, StrSlice, from_utf8_lossy}; +use strbuf::StrBuf; +use slice::{OwnedCloneableVector, OwnedVector, Vector}; use slice::{ImmutableEqVector, ImmutableVector}; +use vec::Vec; /// Typedef for POSIX file paths. /// See `posix::Path` for more info. @@ -184,7 +187,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { fn as_vec<'a>(&'a self) -> &'a [u8]; /// Converts the Path into an owned byte vector - fn into_vec(self) -> ~[u8]; + fn into_vec(self) -> Vec; /// Returns an object that implements `Show` for printing paths /// @@ -293,7 +296,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { let extlen = extension.container_as_bytes().len(); match (name.rposition_elem(&dot), extlen) { (None, 0) | (Some(0), 0) => None, - (Some(idx), 0) => Some(name.slice_to(idx).to_owned()), + (Some(idx), 0) => Some(Vec::from_slice(name.slice_to(idx))), (idx, extlen) => { let idx = match idx { None | Some(0) => name.len(), @@ -301,7 +304,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { }; let mut v; - v = slice::with_capacity(idx + extlen + 1); + v = Vec::with_capacity(idx + extlen + 1); v.push_all(name.slice_to(idx)); v.push(dot); v.push_all(extension.container_as_bytes()); @@ -441,10 +444,10 @@ pub trait GenericPath: Clone + GenericPathUnsafe { pub trait BytesContainer { /// Returns a &[u8] representing the receiver fn container_as_bytes<'a>(&'a self) -> &'a [u8]; - /// Consumes the receiver and converts it into ~[u8] + /// Consumes the receiver and converts it into Vec #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { - self.container_as_bytes().to_owned() + fn container_into_owned_bytes(self) -> Vec { + Vec::from_slice(self.container_as_bytes()) } /// Returns the receiver interpreted as a utf-8 string, if possible #[inline] @@ -522,7 +525,19 @@ impl BytesContainer for ~str { self.as_bytes() } #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { + fn container_as_str<'a>(&'a self) -> Option<&'a str> { + Some(self.as_slice()) + } + #[inline] + fn is_str(_: Option<~str>) -> bool { true } +} +impl BytesContainer for StrBuf { + #[inline] + fn container_as_bytes<'a>(&'a self) -> &'a [u8] { + self.as_bytes() + } + #[inline] + fn container_into_owned_bytes(self) -> Vec { self.into_bytes() } #[inline] @@ -530,7 +545,7 @@ impl BytesContainer for ~str { Some(self.as_slice()) } #[inline] - fn is_str(_: Option<~str>) -> bool { true } + fn is_str(_: Option) -> bool { true } } impl<'a> BytesContainer for &'a [u8] { @@ -545,8 +560,15 @@ impl BytesContainer for ~[u8] { fn container_as_bytes<'a>(&'a self) -> &'a [u8] { self.as_slice() } +} + +impl BytesContainer for Vec { + #[inline] + fn container_as_bytes<'a>(&'a self) -> &'a [u8] { + self.as_slice() + } #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { + fn container_into_owned_bytes(self) -> Vec { self } } @@ -564,10 +586,6 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> { self.as_slice().as_bytes() } #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { - self.into_owned().into_bytes() - } - #[inline] fn container_as_str<'b>(&'b self) -> Option<&'b str> { Some(self.as_slice()) } diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 69504a2ec8fca..1a80e52359d24 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -20,9 +20,10 @@ use iter::{AdditiveIterator, Extendable, Iterator, Map}; use option::{Option, None, Some}; use str; use str::Str; -use slice; use slice::{CloneableVector, RevSplits, Splits, Vector, VectorVector, ImmutableEqVector, OwnedVector, ImmutableVector, OwnedCloneableVector}; +use vec::Vec; + use super::{BytesContainer, GenericPath, GenericPathUnsafe}; /// Iterator that yields successive components of a Path as &[u8] @@ -40,7 +41,7 @@ pub type RevStrComponents<'a> = Map<'a, &'a [u8], Option<&'a str>, /// Represents a POSIX file path #[deriving(Clone)] pub struct Path { - repr: ~[u8], // assumed to never be empty or contain NULs + repr: Vec, // assumed to never be empty or contain NULs sepidx: Option // index of the final separator in repr } @@ -103,7 +104,7 @@ impl BytesContainer for Path { self.as_vec() } #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { + fn container_into_owned_bytes(self) -> Vec { self.into_vec() } } @@ -119,38 +120,41 @@ impl GenericPathUnsafe for Path { unsafe fn new_unchecked(path: T) -> Path { let path = Path::normalize(path.container_as_bytes()); assert!(!path.is_empty()); - let idx = path.rposition_elem(&SEP_BYTE); + let idx = path.as_slice().rposition_elem(&SEP_BYTE); Path{ repr: path, sepidx: idx } } unsafe fn set_filename_unchecked(&mut self, filename: T) { let filename = filename.container_as_bytes(); match self.sepidx { - None if bytes!("..") == self.repr => { - let mut v = slice::with_capacity(3 + filename.len()); + None if bytes!("..") == self.repr.as_slice() => { + let mut v = Vec::with_capacity(3 + filename.len()); v.push_all(dot_dot_static); v.push(SEP_BYTE); v.push_all(filename); - self.repr = Path::normalize(v); + // FIXME: this is slow + self.repr = Path::normalize(v.as_slice()); } None => { self.repr = Path::normalize(filename); } Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => { - let mut v = slice::with_capacity(self.repr.len() + 1 + filename.len()); - v.push_all(self.repr); + let mut v = Vec::with_capacity(self.repr.len() + 1 + filename.len()); + v.push_all(self.repr.as_slice()); v.push(SEP_BYTE); v.push_all(filename); - self.repr = Path::normalize(v); + // FIXME: this is slow + self.repr = Path::normalize(v.as_slice()); } Some(idx) => { - let mut v = slice::with_capacity(idx + 1 + filename.len()); + let mut v = Vec::with_capacity(idx + 1 + filename.len()); v.push_all(self.repr.slice_to(idx+1)); v.push_all(filename); - self.repr = Path::normalize(v); + // FIXME: this is slow + self.repr = Path::normalize(v.as_slice()); } } - self.sepidx = self.repr.rposition_elem(&SEP_BYTE); + self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE); } unsafe fn push_unchecked(&mut self, path: T) { @@ -159,13 +163,14 @@ impl GenericPathUnsafe for Path { if path[0] == SEP_BYTE { self.repr = Path::normalize(path); } else { - let mut v = slice::with_capacity(self.repr.len() + path.len() + 1); - v.push_all(self.repr); + let mut v = Vec::with_capacity(self.repr.len() + path.len() + 1); + v.push_all(self.repr.as_slice()); v.push(SEP_BYTE); v.push_all(path); - self.repr = Path::normalize(v); + // FIXME: this is slow + self.repr = Path::normalize(v.as_slice()); } - self.sepidx = self.repr.rposition_elem(&SEP_BYTE); + self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE); } } } @@ -176,13 +181,13 @@ impl GenericPath for Path { self.repr.as_slice() } - fn into_vec(self) -> ~[u8] { + fn into_vec(self) -> Vec { self.repr } fn dirname<'a>(&'a self) -> &'a [u8] { match self.sepidx { - None if bytes!("..") == self.repr => self.repr.as_slice(), + None if bytes!("..") == self.repr.as_slice() => self.repr.as_slice(), None => dot_static, Some(0) => self.repr.slice_to(1), Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => self.repr.as_slice(), @@ -192,7 +197,8 @@ impl GenericPath for Path { fn filename<'a>(&'a self) -> Option<&'a [u8]> { match self.sepidx { - None if bytes!(".") == self.repr || bytes!("..") == self.repr => None, + None if bytes!(".") == self.repr.as_slice() || + bytes!("..") == self.repr.as_slice() => None, None => Some(self.repr.as_slice()), Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => None, Some(0) if self.repr.slice_from(1).is_empty() => None, @@ -202,20 +208,20 @@ impl GenericPath for Path { fn pop(&mut self) -> bool { match self.sepidx { - None if bytes!(".") == self.repr => false, + None if bytes!(".") == self.repr.as_slice() => false, None => { - self.repr = ~['.' as u8]; + self.repr = vec!['.' as u8]; self.sepidx = None; true } - Some(0) if bytes!("/") == self.repr => false, + Some(0) if bytes!("/") == self.repr.as_slice() => false, Some(idx) => { if idx == 0 { self.repr.truncate(idx+1); } else { self.repr.truncate(idx); } - self.sepidx = self.repr.rposition_elem(&SEP_BYTE); + self.sepidx = self.repr.as_slice().rposition_elem(&SEP_BYTE); true } } @@ -231,7 +237,7 @@ impl GenericPath for Path { #[inline] fn is_absolute(&self) -> bool { - self.repr[0] == SEP_BYTE + *self.repr.get(0) == SEP_BYTE } fn is_ancestor_of(&self, other: &Path) -> bool { @@ -240,7 +246,7 @@ impl GenericPath for Path { } else { let mut ita = self.components(); let mut itb = other.components(); - if bytes!(".") == self.repr { + if bytes!(".") == self.repr.as_slice() { return match itb.next() { None => true, Some(b) => b != bytes!("..") @@ -261,6 +267,7 @@ impl GenericPath for Path { } } + #[allow(deprecated_owned_vector)] fn path_relative_from(&self, base: &Path) -> Option { if self.is_absolute() != base.is_absolute() { if self.is_absolute() { @@ -271,7 +278,7 @@ impl GenericPath for Path { } else { let mut ita = self.components(); let mut itb = base.components(); - let mut comps = ~[]; + let mut comps = vec![]; loop { match (ita.next(), itb.next()) { (None, None) => break, @@ -295,7 +302,7 @@ impl GenericPath for Path { } } } - Some(Path::new(comps.connect_vec(&SEP_BYTE))) + Some(Path::new(comps.as_slice().connect_vec(&SEP_BYTE))) } } @@ -334,7 +341,7 @@ impl Path { /// Returns a normalized byte vector representation of a path, by removing all empty /// components, and unnecessary . and .. components. - fn normalize+CloneableVector>(v: V) -> ~[u8] { + fn normalize+CloneableVector>(v: V) -> Vec { // borrowck is being very picky let val = { let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE; @@ -344,11 +351,11 @@ impl Path { None => None, Some(comps) => { if is_abs && comps.is_empty() { - Some(~[SEP_BYTE]) + Some(vec![SEP_BYTE]) } else { let n = if is_abs { comps.len() } else { comps.len() - 1} + comps.iter().map(|v| v.len()).sum(); - let mut v = slice::with_capacity(n); + let mut v = Vec::with_capacity(n); let mut it = comps.move_iter(); if !is_abs { match it.next() { @@ -366,7 +373,7 @@ impl Path { } }; match val { - None => v.into_owned(), + None => Vec::from_slice(v.as_slice()), Some(val) => val } } @@ -376,7 +383,7 @@ impl Path { /// /a/b/c and a/b/c yield the same set of components. /// A path of "/" yields no components. A path of "." yields one component. pub fn components<'a>(&'a self) -> Components<'a> { - let v = if self.repr[0] == SEP_BYTE { + let v = if *self.repr.get(0) == SEP_BYTE { self.repr.slice_from(1) } else { self.repr.as_slice() }; let mut ret = v.split(is_sep_byte); @@ -390,7 +397,7 @@ impl Path { /// Returns an iterator that yields each component of the path in reverse. /// See components() for details. pub fn rev_components<'a>(&'a self) -> RevComponents<'a> { - let v = if self.repr[0] == SEP_BYTE { + let v = if *self.repr.get(0) == SEP_BYTE { self.repr.slice_from(1) } else { self.repr.as_slice() }; let mut ret = v.rsplit(is_sep_byte); @@ -415,11 +422,11 @@ impl Path { } // None result means the byte vector didn't need normalizing -fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<~[&'a [u8]]> { +fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option> { if is_abs && v.as_slice().is_empty() { return None; } - let mut comps: ~[&'a [u8]] = ~[]; + let mut comps: Vec<&'a [u8]> = vec![]; let mut n_up = 0u; let mut changed = false; for comp in v.split(is_sep_byte) { @@ -511,9 +518,9 @@ mod tests { t!(s: Path::new("foo/../../.."), "../.."); t!(s: Path::new("foo/../../bar"), "../bar"); - assert!(Path::new(b!("foo/bar")).into_vec() == b!("foo/bar").to_owned()); - assert!(Path::new(b!("/foo/../../bar")).into_vec() == - b!("/bar").to_owned()); + assert_eq!(Path::new(b!("foo/bar")).into_vec().as_slice(), b!("foo/bar")); + assert_eq!(Path::new(b!("/foo/../../bar")).into_vec().as_slice(), + b!("/bar")); let p = Path::new(b!("foo/bar", 0x80)); assert!(p.as_str() == None); @@ -762,7 +769,7 @@ mod tests { t!(s: "a/b/c", [~"d", ~"e"], "a/b/c/d/e"); t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e")); t!(v: b!("a/b/c"), [b!("d"), b!("/e"), b!("f")], b!("/e/f")); - t!(v: b!("a/b/c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a/b/c/d/e")); + t!(v: b!("a/b/c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], b!("a/b/c/d/e")); } #[test] @@ -866,7 +873,7 @@ mod tests { t!(s: "a/b/c", ["d", "/e", "f"], "/e/f"); t!(s: "a/b/c", [~"d", ~"e"], "a/b/c/d/e"); t!(v: b!("a/b/c"), [b!("d"), b!("e")], b!("a/b/c/d/e")); - t!(v: b!("a/b/c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a/b/c/d/e")); + t!(v: b!("a/b/c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], b!("a/b/c/d/e")); } #[test] @@ -1179,13 +1186,13 @@ mod tests { (s: $path:expr, $exp:expr) => ( { let path = Path::new($path); - let comps = path.components().collect::<~[&[u8]]>(); + let comps = path.components().collect::>(); let exp: &[&str] = $exp; - let exps = exp.iter().map(|x| x.as_bytes()).collect::<~[&[u8]]>(); + let exps = exp.iter().map(|x| x.as_bytes()).collect::>(); assert!(comps == exps, "components: Expected {:?}, found {:?}", comps, exps); - let comps = path.rev_components().collect::<~[&[u8]]>(); - let exps = exps.move_rev_iter().collect::<~[&[u8]]>(); + let comps = path.rev_components().collect::>(); + let exps = exps.move_iter().rev().collect::>(); assert!(comps == exps, "rev_components: Expected {:?}, found {:?}", comps, exps); } @@ -1193,15 +1200,12 @@ mod tests { (v: [$($arg:expr),+], [$([$($exp:expr),*]),*]) => ( { let path = Path::new(b!($($arg),+)); - let comps = path.components().collect::<~[&[u8]]>(); + let comps = path.components().collect::>(); let exp: &[&[u8]] = [$(b!($($exp),*)),*]; - assert!(comps.as_slice() == exp, "components: Expected {:?}, found {:?}", - comps.as_slice(), exp); - let comps = path.rev_components().collect::<~[&[u8]]>(); - let exp = exp.rev_iter().map(|&x|x).collect::<~[&[u8]]>(); - assert!(comps.as_slice() == exp, - "rev_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + assert_eq!(comps.as_slice(), exp); + let comps = path.rev_components().collect::>(); + let exp = exp.rev_iter().map(|&x|x).collect::>(); + assert_eq!(comps, exp) } ) ) @@ -1228,16 +1232,12 @@ mod tests { (v: [$($arg:expr),+], $exp:expr) => ( { let path = Path::new(b!($($arg),+)); - let comps = path.str_components().collect::<~[Option<&str>]>(); + let comps = path.str_components().collect::>>(); let exp: &[Option<&str>] = $exp; - assert!(comps.as_slice() == exp, - "str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); - let comps = path.rev_str_components().collect::<~[Option<&str>]>(); - let exp = exp.rev_iter().map(|&x|x).collect::<~[Option<&str>]>(); - assert!(comps.as_slice() == exp, - "rev_str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + assert_eq!(comps.as_slice(), exp); + let comps = path.rev_str_components().collect::>>(); + let exp = exp.rev_iter().map(|&x|x).collect::>>(); + assert_eq!(comps, exp); } ) ) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 93d8d9e3eb416..435b64e8d2afd 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -22,8 +22,9 @@ use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Rev, Iterator, Map use option::{Option, Some, None}; use slice::{Vector, OwnedVector, ImmutableVector}; use str::{CharSplits, OwnedStr, Str, StrVector, StrSlice}; -use str; use strbuf::StrBuf; +use vec::Vec; + use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe}; /// Iterator that yields successive components of a Path as &str @@ -82,7 +83,7 @@ pub type RevComponents<'a> = Map<'a, Option<&'a str>, &'a [u8], // preserved by the data structure; let the Windows API error out on them. #[deriving(Clone)] pub struct Path { - repr: ~str, // assumed to never be empty + repr: StrBuf, // assumed to never be empty prefix: Option, sepidx: Option // index of the final separator in the non-prefix portion of repr } @@ -128,7 +129,7 @@ impl BytesContainer for Path { self.as_vec() } #[inline] - fn container_into_owned_bytes(self) -> ~[u8] { + fn container_into_owned_bytes(self) -> Vec { self.into_vec() } #[inline] @@ -175,7 +176,7 @@ impl GenericPathUnsafe for Path { unsafe fn set_filename_unchecked(&mut self, filename: T) { let filename = filename.container_as_str().unwrap(); match self.sepidx_or_prefix_len() { - None if ".." == self.repr => { + None if ".." == self.repr.as_slice() => { let mut s = StrBuf::with_capacity(3 + filename.len()); s.push_str(".."); s.push_char(SEP); @@ -185,22 +186,22 @@ impl GenericPathUnsafe for Path { None => { self.update_normalized(filename); } - Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => { + Some((_,idxa,end)) if self.repr.as_slice().slice(idxa,end) == ".." => { let mut s = StrBuf::with_capacity(end + 1 + filename.len()); - s.push_str(self.repr.slice_to(end)); + s.push_str(self.repr.as_slice().slice_to(end)); s.push_char(SEP); s.push_str(filename); self.update_normalized(s); } Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => { let mut s = StrBuf::with_capacity(idxb + filename.len()); - s.push_str(self.repr.slice_to(idxb)); + s.push_str(self.repr.as_slice().slice_to(idxb)); s.push_str(filename); self.update_normalized(s); } Some((idxb,_,_)) => { let mut s = StrBuf::with_capacity(idxb + 1 + filename.len()); - s.push_str(self.repr.slice_to(idxb)); + s.push_str(self.repr.as_slice().slice_to(idxb)); s.push_char(SEP); s.push_str(filename); self.update_normalized(s); @@ -227,9 +228,10 @@ impl GenericPathUnsafe for Path { } fn shares_volume(me: &Path, path: &str) -> bool { // path is assumed to have a prefix of Some(DiskPrefix) + let repr = me.repr.as_slice(); match me.prefix { - Some(DiskPrefix) => me.repr[0] == path[0].to_ascii().to_upper().to_byte(), - Some(VerbatimDiskPrefix) => me.repr[4] == path[0].to_ascii().to_upper().to_byte(), + Some(DiskPrefix) => repr[0] == path[0].to_ascii().to_upper().to_byte(), + Some(VerbatimDiskPrefix) => repr[4] == path[0].to_ascii().to_upper().to_byte(), _ => false } } @@ -242,7 +244,7 @@ impl GenericPathUnsafe for Path { let newpath = Path::normalize__(path, prefix); me.repr = match newpath { Some(p) => p, - None => path.to_owned() + None => StrBuf::from_str(path) }; me.prefix = prefix; me.update_sepidx(); @@ -254,19 +256,19 @@ impl GenericPathUnsafe for Path { else { None }; let pathlen = path_.as_ref().map_or(path.len(), |p| p.len()); let mut s = StrBuf::with_capacity(me.repr.len() + 1 + pathlen); - s.push_str(me.repr); + s.push_str(me.repr.as_slice()); let plen = me.prefix_len(); // if me is "C:" we don't want to add a path separator match me.prefix { Some(DiskPrefix) if me.repr.len() == plen => (), - _ if !(me.repr.len() > plen && me.repr[me.repr.len()-1] == SEP_BYTE) => { + _ if !(me.repr.len() > plen && me.repr.as_slice()[me.repr.len()-1] == SEP_BYTE) => { s.push_char(SEP); } _ => () } match path_ { None => s.push_str(path), - Some(p) => s.push_str(p) + Some(p) => s.push_str(p.as_slice()) }; me.update_normalized(s) } @@ -331,8 +333,8 @@ impl GenericPath for Path { } #[inline] - fn into_vec(self) -> ~[u8] { - self.repr.into_bytes() + fn into_vec(self) -> Vec { + Vec::from_slice(self.repr.as_bytes()) } #[inline] @@ -344,21 +346,21 @@ impl GenericPath for Path { /// Always returns a `Some` value. fn dirname_str<'a>(&'a self) -> Option<&'a str> { Some(match self.sepidx_or_prefix_len() { - None if ".." == self.repr => self.repr.as_slice(), + None if ".." == self.repr.as_slice() => self.repr.as_slice(), None => ".", - Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => { + Some((_,idxa,end)) if self.repr.as_slice().slice(idxa, end) == ".." => { self.repr.as_slice() } - Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => { + Some((idxb,_,end)) if self.repr.as_slice().slice(idxb, end) == "\\" => { self.repr.as_slice() } - Some((0,idxa,_)) => self.repr.slice_to(idxa), + Some((0,idxa,_)) => self.repr.as_slice().slice_to(idxa), Some((idxb,idxa,_)) => { match self.prefix { Some(DiskPrefix) | Some(VerbatimDiskPrefix) if idxb == self.prefix_len() => { - self.repr.slice_to(idxa) + self.repr.as_slice().slice_to(idxa) } - _ => self.repr.slice_to(idxb) + _ => self.repr.as_slice().slice_to(idxb) } } }) @@ -372,12 +374,13 @@ impl GenericPath for Path { /// See `GenericPath::filename_str` for info. /// Always returns a `Some` value if `filename` returns a `Some` value. fn filename_str<'a>(&'a self) -> Option<&'a str> { + let repr = self.repr.as_slice(); match self.sepidx_or_prefix_len() { - None if "." == self.repr || ".." == self.repr => None, - None => Some(self.repr.as_slice()), - Some((_,idxa,end)) if self.repr.slice(idxa, end) == ".." => None, + None if "." == repr || ".." == repr => None, + None => Some(repr), + Some((_,idxa,end)) if repr.slice(idxa, end) == ".." => None, Some((_,idxa,end)) if idxa == end => None, - Some((_,idxa,end)) => Some(self.repr.slice(idxa, end)) + Some((_,idxa,end)) => Some(repr.slice(idxa, end)) } } @@ -402,14 +405,14 @@ impl GenericPath for Path { #[inline] fn pop(&mut self) -> bool { match self.sepidx_or_prefix_len() { - None if "." == self.repr => false, + None if "." == self.repr.as_slice() => false, None => { - self.repr = ~"."; + self.repr = StrBuf::from_str("."); self.sepidx = None; true } Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false, - Some((idxb,_,end)) if self.repr.slice(idxb, end) == "\\" => false, + Some((idxb,_,end)) if self.repr.as_slice().slice(idxb, end) == "\\" => false, Some((idxb,idxa,_)) => { let trunc = match self.prefix { Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => { @@ -429,15 +432,15 @@ impl GenericPath for Path { if self.prefix.is_some() { Some(Path::new(match self.prefix { Some(DiskPrefix) if self.is_absolute() => { - self.repr.slice_to(self.prefix_len()+1) + self.repr.as_slice().slice_to(self.prefix_len()+1) } Some(VerbatimDiskPrefix) => { - self.repr.slice_to(self.prefix_len()+1) + self.repr.as_slice().slice_to(self.prefix_len()+1) } - _ => self.repr.slice_to(self.prefix_len()) + _ => self.repr.as_slice().slice_to(self.prefix_len()) })) } else if is_vol_relative(self) { - Some(Path::new(self.repr.slice_to(1))) + Some(Path::new(self.repr.as_slice().slice_to(1))) } else { None } @@ -456,7 +459,7 @@ impl GenericPath for Path { fn is_absolute(&self) -> bool { match self.prefix { Some(DiskPrefix) => { - let rest = self.repr.slice_from(self.prefix_len()); + let rest = self.repr.as_slice().slice_from(self.prefix_len()); rest.len() > 0 && rest[0] == SEP_BYTE } Some(_) => true, @@ -478,7 +481,7 @@ impl GenericPath for Path { } else { let mut ita = self.str_components().map(|x|x.unwrap()); let mut itb = other.str_components().map(|x|x.unwrap()); - if "." == self.repr { + if "." == self.repr.as_slice() { return itb.next() != Some(".."); } loop { @@ -526,7 +529,7 @@ impl GenericPath for Path { } else { let mut ita = self.str_components().map(|x|x.unwrap()); let mut itb = base.str_components().map(|x|x.unwrap()); - let mut comps = ~[]; + let mut comps = vec![]; let a_verb = is_verbatim(self); let b_verb = is_verbatim(base); @@ -613,15 +616,16 @@ impl Path { /// Does not distinguish between absolute and cwd-relative paths, e.g. /// C:\foo and C:foo. pub fn str_components<'a>(&'a self) -> StrComponents<'a> { + let repr = self.repr.as_slice(); let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); - if self.repr.len() > plen && self.repr[plen] == SEP_BYTE { - self.repr.slice_from(plen+1) - } else { self.repr.slice_from(plen) } + if repr.len() > plen && repr[plen] == SEP_BYTE { + repr.slice_from(plen+1) + } else { repr.slice_from(plen) } } - None if self.repr[0] == SEP_BYTE => self.repr.slice_from(1), - None => self.repr.as_slice() + None if repr[0] == SEP_BYTE => repr.slice_from(1), + None => repr }; let ret = s.split_terminator(SEP).map(Some); ret @@ -654,33 +658,35 @@ impl Path { } fn equiv_prefix(&self, other: &Path) -> bool { + let s_repr = self.repr.as_slice(); + let o_repr = other.repr.as_slice(); match (self.prefix, other.prefix) { (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => { self.is_absolute() && - self.repr[0].to_ascii().eq_ignore_case(other.repr[4].to_ascii()) + s_repr[0].to_ascii().eq_ignore_case(o_repr[4].to_ascii()) } (Some(VerbatimDiskPrefix), Some(DiskPrefix)) => { other.is_absolute() && - self.repr[4].to_ascii().eq_ignore_case(other.repr[0].to_ascii()) + s_repr[4].to_ascii().eq_ignore_case(o_repr[0].to_ascii()) } (Some(VerbatimDiskPrefix), Some(VerbatimDiskPrefix)) => { - self.repr[4].to_ascii().eq_ignore_case(other.repr[4].to_ascii()) + s_repr[4].to_ascii().eq_ignore_case(o_repr[4].to_ascii()) } (Some(UNCPrefix(_,_)), Some(VerbatimUNCPrefix(_,_))) => { - self.repr.slice(2, self.prefix_len()) == other.repr.slice(8, other.prefix_len()) + s_repr.slice(2, self.prefix_len()) == o_repr.slice(8, other.prefix_len()) } (Some(VerbatimUNCPrefix(_,_)), Some(UNCPrefix(_,_))) => { - self.repr.slice(8, self.prefix_len()) == other.repr.slice(2, other.prefix_len()) + s_repr.slice(8, self.prefix_len()) == o_repr.slice(2, other.prefix_len()) } (None, None) => true, (a, b) if a == b => { - self.repr.slice_to(self.prefix_len()) == other.repr.slice_to(other.prefix_len()) + s_repr.slice_to(self.prefix_len()) == o_repr.slice_to(other.prefix_len()) } _ => false } } - fn normalize_(s: S) -> (Option, ~str) { + fn normalize_(s: S) -> (Option, StrBuf) { // make borrowck happy let (prefix, val) = { let prefix = parse_prefix(s.as_slice()); @@ -688,20 +694,20 @@ impl Path { (prefix, path) }; (prefix, match val { - None => s.into_owned(), + None => s.into_strbuf(), Some(val) => val }) } - fn normalize__(s: &str, prefix: Option) -> Option<~str> { + fn normalize__(s: &str, prefix: Option) -> Option { if prefix_is_verbatim(prefix) { // don't do any normalization match prefix { Some(VerbatimUNCPrefix(x, 0)) if s.len() == 8 + x => { // the server component has no trailing '\' - let mut s = StrBuf::from_owned_str(s.into_owned()); + let mut s = StrBuf::from_str(s); s.push_char(SEP); - Some(s.into_owned()) + Some(s) } _ => None } @@ -711,12 +717,12 @@ impl Path { match (comps.is_some(),prefix) { (false, Some(DiskPrefix)) => { if s[0] >= 'a' as u8 && s[0] <= 'z' as u8 { - comps = Some(~[]); + comps = Some(vec![]); } } (false, Some(VerbatimDiskPrefix)) => { if s[4] >= 'a' as u8 && s[0] <= 'z' as u8 { - comps = Some(~[]); + comps = Some(vec![]); } } _ => () @@ -728,37 +734,37 @@ impl Path { match prefix.unwrap() { DiskPrefix => { let len = prefix_len(prefix) + is_abs as uint; - let mut s = s.slice_to(len).to_owned(); + let mut s = StrBuf::from_str(s.slice_to(len)); unsafe { - str::raw::as_owned_vec(&mut s)[0] = - s[0].to_ascii().to_upper().to_byte(); + let v = s.as_mut_vec(); + *v.get_mut(0) = v.get(0).to_ascii().to_upper().to_byte(); } if is_abs { // normalize C:/ to C:\ unsafe { - str::raw::as_owned_vec(&mut s)[2] = SEP_BYTE; + *s.as_mut_vec().get_mut(2) = SEP_BYTE; } } Some(s) } VerbatimDiskPrefix => { let len = prefix_len(prefix) + is_abs as uint; - let mut s = s.slice_to(len).to_owned(); + let mut s = StrBuf::from_str(s.slice_to(len)); unsafe { - str::raw::as_owned_vec(&mut s)[4] = - s[4].to_ascii().to_upper().to_byte(); + let v = s.as_mut_vec(); + *v.get_mut(4) = v.get(4).to_ascii().to_upper().to_byte(); } Some(s) } _ => { let plen = prefix_len(prefix); if s.len() > plen { - Some(s.slice_to(plen).to_owned()) + Some(StrBuf::from_str(s.slice_to(plen))) } else { None } } } } else if is_abs && comps.is_empty() { - Some(str::from_char(SEP)) + Some(StrBuf::from_char(1, SEP)) } else { let prefix_ = s.slice_to(prefix_len(prefix)); let n = prefix_.len() + @@ -795,7 +801,7 @@ impl Path { s.push_char(SEP); s.push_str(comp); } - Some(s.into_owned()) + Some(s) } } } @@ -804,7 +810,7 @@ impl Path { fn update_sepidx(&mut self) { let s = if self.has_nonsemantic_trailing_slash() { - self.repr.slice_to(self.repr.len()-1) + self.repr.as_slice().slice_to(self.repr.len()-1) } else { self.repr.as_slice() }; let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep } else { is_sep_verbatim }); @@ -834,7 +840,7 @@ impl Path { fn has_nonsemantic_trailing_slash(&self) -> bool { is_verbatim(self) && self.repr.len() > self.prefix_len()+1 && - self.repr[self.repr.len()-1] == SEP_BYTE + self.repr.as_slice()[self.repr.len()-1] == SEP_BYTE } fn update_normalized(&mut self, s: S) { @@ -850,7 +856,7 @@ impl Path { /// but absolute within that volume. #[inline] pub fn is_vol_relative(path: &Path) -> bool { - path.prefix.is_none() && is_sep_byte(&path.repr[0]) + path.prefix.is_none() && is_sep_byte(&path.repr.as_slice()[0]) } /// Returns whether the path is considered "cwd-relative", which means a path @@ -880,16 +886,17 @@ pub fn is_verbatim(path: &Path) -> bool { /// non-verbatim, the non-verbatim version is returned. /// Otherwise, None is returned. pub fn make_non_verbatim(path: &Path) -> Option { + let repr = path.repr.as_slice(); let new_path = match path.prefix { Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None, Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()), Some(VerbatimDiskPrefix) => { // \\?\D:\ - Path::new(path.repr.slice_from(4)) + Path::new(repr.slice_from(4)) } Some(VerbatimUNCPrefix(_,_)) => { // \\?\UNC\server\share - Path::new(format!(r"\\{}", path.repr.slice_from(7))) + Path::new(format!(r"\\{}", repr.slice_from(7))) } }; if new_path.prefix.is_none() { @@ -898,7 +905,8 @@ pub fn make_non_verbatim(path: &Path) -> Option { return None; } // now ensure normalization didn't change anything - if path.repr.slice_from(path.prefix_len()) == new_path.repr.slice_from(new_path.prefix_len()) { + if repr.slice_from(path.prefix_len()) == + new_path.repr.as_slice().slice_from(new_path.prefix_len()) { Some(new_path) } else { None @@ -1023,7 +1031,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option { } // None result means the string didn't need normalizing -fn normalize_helper<'a>(s: &'a str, prefix: Option) -> (bool,Option<~[&'a str]>) { +fn normalize_helper<'a>(s: &'a str, prefix: Option) -> (bool, Option>) { let f = if !prefix_is_verbatim(prefix) { is_sep } else { is_sep_verbatim }; let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix))); let s_ = s.slice_from(prefix_len(prefix)); @@ -1032,11 +1040,11 @@ fn normalize_helper<'a>(s: &'a str, prefix: Option) -> (bool,Option< if is_abs && s_.is_empty() { return (is_abs, match prefix { Some(DiskPrefix) | None => (if is_sep_verbatim(s.char_at(prefix_len(prefix))) { None } - else { Some(~[]) }), - Some(_) => Some(~[]), // need to trim the trailing separator + else { Some(vec![]) }), + Some(_) => Some(vec![]), // need to trim the trailing separator }); } - let mut comps: ~[&'a str] = ~[]; + let mut comps: Vec<&'a str> = vec![]; let mut n_up = 0u; let mut changed = false; for comp in s_.split(f) { @@ -1217,9 +1225,8 @@ mod tests { t!(s: Path::new("foo\\..\\..\\.."), "..\\.."); t!(s: Path::new("foo\\..\\..\\bar"), "..\\bar"); - assert_eq!(Path::new(b!("foo\\bar")).into_vec(), b!("foo\\bar").to_owned()); - assert_eq!(Path::new(b!("\\foo\\..\\..\\bar")).into_vec(), - b!("\\bar").to_owned()); + assert_eq!(Path::new(b!("foo\\bar")).into_vec().as_slice(), b!("foo\\bar")); + assert_eq!(Path::new(b!("\\foo\\..\\..\\bar")).into_vec().as_slice(), b!("\\bar")); t!(s: Path::new("\\\\a"), "\\a"); t!(s: Path::new("\\\\a\\"), "\\a"); @@ -1573,7 +1580,8 @@ mod tests { t!(s: "a\\b\\c", [~"d", ~"e"], "a\\b\\c\\d\\e"); t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e")); t!(v: b!("a\\b\\c"), [b!("d"), b!("\\e"), b!("f")], b!("\\e\\f")); - t!(v: b!("a\\b\\c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a\\b\\c\\d\\e")); + t!(v: b!("a\\b\\c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], + b!("a\\b\\c\\d\\e")); } #[test] @@ -1712,7 +1720,8 @@ mod tests { t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f"); t!(s: "a\\b\\c", [~"d", ~"e"], "a\\b\\c\\d\\e"); t!(v: b!("a\\b\\c"), [b!("d"), b!("e")], b!("a\\b\\c\\d\\e")); - t!(v: b!("a\\b\\c"), [b!("d").to_owned(), b!("e").to_owned()], b!("a\\b\\c\\d\\e")); + t!(v: b!("a\\b\\c"), [Vec::from_slice(b!("d")), Vec::from_slice(b!("e"))], + b!("a\\b\\c\\d\\e")); } #[test] @@ -2227,33 +2236,25 @@ mod tests { { let path = Path::new($path); let comps = path.str_components().map(|x|x.unwrap()) - .collect::<~[&str]>(); + .collect::>(); let exp: &[&str] = $exp; - assert!(comps.as_slice() == exp, - "str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + assert_eq!(comps.as_slice(), exp); let comps = path.rev_str_components().map(|x|x.unwrap()) - .collect::<~[&str]>(); - let exp = exp.rev_iter().map(|&x|x).collect::<~[&str]>(); - assert!(comps.as_slice() == exp, - "rev_str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + .collect::>(); + let exp = exp.rev_iter().map(|&x|x).collect::>(); + assert_eq!(comps, exp); } ); (v: [$($arg:expr),+], $exp:expr) => ( { let path = Path::new(b!($($arg),+)); - let comps = path.str_components().map(|x|x.unwrap()).collect::<~[&str]>(); + let comps = path.str_components().map(|x|x.unwrap()).collect::>(); let exp: &[&str] = $exp; - assert!(comps.as_slice() == exp, - "str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + assert_eq!(comps.as_slice(), exp); let comps = path.rev_str_components().map(|x|x.unwrap()) - .collect::<~[&str]>(); - let exp = exp.rev_iter().map(|&x|x).collect::<~[&str]>(); - assert!(comps.as_slice() == exp, - "rev_str_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + .collect::>(); + let exp = exp.rev_iter().map(|&x|x).collect::>(); + assert_eq!(comps, exp); } ) ) @@ -2304,15 +2305,12 @@ mod tests { (s: $path:expr, $exp:expr) => ( { let path = Path::new($path); - let comps = path.components().collect::<~[&[u8]]>(); + let comps = path.components().collect::>(); let exp: &[&[u8]] = $exp; - assert!(comps.as_slice() == exp, "components: Expected {:?}, found {:?}", - comps.as_slice(), exp); - let comps = path.rev_components().collect::<~[&[u8]]>(); - let exp = exp.rev_iter().map(|&x|x).collect::<~[&[u8]]>(); - assert!(comps.as_slice() == exp, - "rev_components: Expected {:?}, found {:?}", - comps.as_slice(), exp); + assert_eq!(comps.as_slice(), exp); + let comps = path.rev_components().collect::>(); + let exp = exp.rev_iter().map(|&x|x).collect::>(); + assert_eq!(comps, exp); } ) ) diff --git a/src/libstd/strbuf.rs b/src/libstd/strbuf.rs index c2add625a773a..873b7293032cf 100644 --- a/src/libstd/strbuf.rs +++ b/src/libstd/strbuf.rs @@ -229,6 +229,13 @@ impl StrBuf { *self = self.as_slice().slice(1, len).into_strbuf(); Some(byte) } + + /// Views the string buffer as a mutable sequence of bytes. + /// + /// Callers must preserve the valid UTF-8 property. + pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec { + &mut self.vec + } } impl Container for StrBuf { @@ -271,6 +278,9 @@ impl Str for StrBuf { cast::transmute::<~[u8],~str>(vec.move_iter().collect()) } } + + #[inline] + fn into_strbuf(self) -> StrBuf { self } } impl fmt::Show for StrBuf {