提交 5dd94d86 编写于 作者: B bors

auto merge of #13481 : huonw/rust/devec-path, r=alexcrichton

Remove the use of ~[] from Path's internals.
......@@ -63,6 +63,8 @@
*/
#![deny(deprecated_owned_vector)]
use container::Container;
use c_str::CString;
use clone::Clone;
......@@ -70,10 +72,11 @@
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 @@ fn as_str<'a>(&'a self) -> Option<&'a str> {
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<u8>;
/// Returns an object that implements `Show` for printing paths
///
......@@ -293,7 +296,7 @@ fn set_extension<T: BytesContainer>(&mut self, extension: T) {
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 @@ fn set_extension<T: BytesContainer>(&mut self, extension: T) {
};
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 @@ fn is_relative(&self) -> bool {
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<u8>
#[inline]
fn container_into_owned_bytes(self) -> ~[u8] {
self.container_as_bytes().to_owned()
fn container_into_owned_bytes(self) -> Vec<u8> {
Vec::from_slice(self.container_as_bytes())
}
/// Returns the receiver interpreted as a utf-8 string, if possible
#[inline]
......@@ -522,7 +525,19 @@ fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
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<u8> {
self.into_bytes()
}
#[inline]
......@@ -530,7 +545,7 @@ fn container_as_str<'a>(&'a self) -> Option<&'a str> {
Some(self.as_slice())
}
#[inline]
fn is_str(_: Option<~str>) -> bool { true }
fn is_str(_: Option<StrBuf>) -> 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<u8> {
#[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<u8> {
self
}
}
......@@ -564,10 +586,6 @@ fn container_as_bytes<'b>(&'b self) -> &'b [u8] {
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())
}
......
......@@ -20,9 +20,10 @@
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 @@
/// Represents a POSIX file path
#[deriving(Clone)]
pub struct Path {
repr: ~[u8], // assumed to never be empty or contain NULs
repr: Vec<u8>, // assumed to never be empty or contain NULs
sepidx: Option<uint> // index of the final separator in repr
}
......@@ -103,7 +104,7 @@ fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
self.as_vec()
}
#[inline]
fn container_into_owned_bytes(self) -> ~[u8] {
fn container_into_owned_bytes(self) -> Vec<u8> {
self.into_vec()
}
}
......@@ -119,38 +120,41 @@ impl GenericPathUnsafe for Path {
unsafe fn new_unchecked<T: BytesContainer>(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<T: BytesContainer>(&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<T: BytesContainer>(&mut self, path: T) {
......@@ -159,13 +163,14 @@ unsafe fn push_unchecked<T: BytesContainer>(&mut self, path: T) {
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 @@ fn as_vec<'a>(&'a self) -> &'a [u8] {
self.repr.as_slice()
}
fn into_vec(self) -> ~[u8] {
fn into_vec(self) -> Vec<u8> {
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 @@ fn dirname<'a>(&'a self) -> &'a [u8] {
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 @@ fn filename<'a>(&'a self) -> Option<&'a [u8]> {
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 @@ fn root_path(&self) -> Option<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 @@ fn is_ancestor_of(&self, other: &Path) -> bool {
} 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 @@ fn is_ancestor_of(&self, other: &Path) -> bool {
}
}
#[allow(deprecated_owned_vector)]
fn path_relative_from(&self, base: &Path) -> Option<Path> {
if self.is_absolute() != base.is_absolute() {
if self.is_absolute() {
......@@ -271,7 +278,7 @@ fn path_relative_from(&self, base: &Path) -> Option<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 @@ fn path_relative_from(&self, base: &Path) -> Option<Path> {
}
}
}
Some(Path::new(comps.connect_vec(&SEP_BYTE)))
Some(Path::new(comps.as_slice().connect_vec(&SEP_BYTE)))
}
}
......@@ -334,7 +341,7 @@ pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
/// Returns a normalized byte vector representation of a path, by removing all empty
/// components, and unnecessary . and .. components.
fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> ~[u8] {
fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> Vec<u8> {
// 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 @@ fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> ~[u8] {
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 @@ fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> ~[u8] {
}
};
match val {
None => v.into_owned(),
None => Vec::from_slice(v.as_slice()),
Some(val) => val
}
}
......@@ -376,7 +383,7 @@ fn normalize<V: Vector<u8>+CloneableVector<u8>>(v: V) -> ~[u8] {
/// /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 @@ pub fn components<'a>(&'a self) -> Components<'a> {
/// 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 @@ pub fn rev_str_components<'a>(&'a self) -> RevStrComponents<'a> {
}
// 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<Vec<&'a [u8]>> {
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 @@ fn test_paths() {
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 @@ fn test_push_many() {
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 @@ fn test_join_many() {
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 @@ fn test_components_iter() {
(s: $path:expr, $exp:expr) => (
{
let path = Path::new($path);
let comps = path.components().collect::<~[&[u8]]>();
let comps = path.components().collect::<Vec<&[u8]>>();
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::<Vec<&[u8]>>();
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::<Vec<&[u8]>>();
let exps = exps.move_iter().rev().collect::<Vec<&[u8]>>();
assert!(comps == exps, "rev_components: Expected {:?}, found {:?}",
comps, exps);
}
......@@ -1193,15 +1200,12 @@ fn test_components_iter() {
(v: [$($arg:expr),+], [$([$($exp:expr),*]),*]) => (
{
let path = Path::new(b!($($arg),+));
let comps = path.components().collect::<~[&[u8]]>();
let comps = path.components().collect::<Vec<&[u8]>>();
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::<Vec<&[u8]>>();
let exp = exp.rev_iter().map(|&x|x).collect::<Vec<&[u8]>>();
assert_eq!(comps, exp)
}
)
)
......@@ -1228,16 +1232,12 @@ fn test_str_components() {
(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::<Vec<Option<&str>>>();
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::<Vec<Option<&str>>>();
let exp = exp.rev_iter().map(|&x|x).collect::<Vec<Option<&str>>>();
assert_eq!(comps, exp);
}
)
)
......
此差异已折叠。
......@@ -229,6 +229,13 @@ pub unsafe fn shift_byte(&mut self) -> Option<u8> {
*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<u8> {
&mut self.vec
}
}
impl Container for StrBuf {
......@@ -271,6 +278,9 @@ fn into_owned(self) -> ~str {
cast::transmute::<~[u8],~str>(vec.move_iter().collect())
}
}
#[inline]
fn into_strbuf(self) -> StrBuf { self }
}
impl fmt::Show for StrBuf {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册