From d1e20488a5d1258b1582caa2db77e5210b8bd28f Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 8 Apr 2014 02:30:08 +0100 Subject: [PATCH 1/2] Parameterize contains_nul for BytesContainer. --- src/libstd/path/mod.rs | 14 +++++++------- src/libstd/path/windows.rs | 9 ++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index a0097469e56a2..54a8d8131375c 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -158,7 +158,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// See individual Path impls for additional restrictions. #[inline] fn new(path: T) -> Self { - assert!(!contains_nul(path.container_as_bytes())); + assert!(!contains_nul(&path)); unsafe { GenericPathUnsafe::new_unchecked(path) } } @@ -166,7 +166,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// The resulting Path will always be normalized. #[inline] fn new_opt(path: T) -> Option { - if contains_nul(path.container_as_bytes()) { + if contains_nul(&path) { None } else { Some(unsafe { GenericPathUnsafe::new_unchecked(path) }) @@ -274,7 +274,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// Fails the task if the filename contains a NUL. #[inline] fn set_filename(&mut self, filename: T) { - assert!(!contains_nul(filename.container_as_bytes())); + assert!(!contains_nul(&filename)); unsafe { self.set_filename_unchecked(filename) } } /// Replaces the extension with the given byte vector or string. @@ -286,7 +286,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// /// Fails the task if the extension contains a NUL. fn set_extension(&mut self, extension: T) { - assert!(!contains_nul(extension.container_as_bytes())); + assert!(!contains_nul(&extension)); // borrowck causes problems here too let val = { match self.filename() { @@ -376,7 +376,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// Fails the task if the path contains a NUL. #[inline] fn push(&mut self, path: T) { - assert!(!contains_nul(path.container_as_bytes())); + assert!(!contains_nul(&path)); unsafe { self.push_unchecked(path) } } /// Pushes multiple paths (as byte vectors or strings) onto `self`. @@ -589,8 +589,8 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> { } #[inline(always)] -fn contains_nul(v: &[u8]) -> bool { - v.iter().any(|&x| x == 0) +fn contains_nul(v: &T) -> bool { + v.container_as_bytes().iter().any(|&x| x == 0) } #[cfg(test)] diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 57dae68b8427b..93d8d9e3eb416 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -306,14 +306,13 @@ impl GenericPathUnsafe for Path { impl GenericPath for Path { #[inline] fn new_opt(path: T) -> Option { - let s = path.container_as_str(); - match s { + match path.container_as_str() { None => None, - Some(s) => { - if contains_nul(s.as_bytes()) { + Some(ref s) => { + if contains_nul(s) { None } else { - Some(unsafe { GenericPathUnsafe::new_unchecked(s) }) + Some(unsafe { GenericPathUnsafe::new_unchecked(*s) }) } } } From 9b9ad9b741bcab9669b9a64dd8004382290dfa47 Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Tue, 8 Apr 2014 03:13:23 +0100 Subject: [PATCH 2/2] Simplify GenericPath::set_extension. --- src/libstd/path/mod.rs | 55 ++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 54a8d8131375c..660f92d8f7b92 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -287,42 +287,29 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// Fails the task if the extension contains a NUL. fn set_extension(&mut self, extension: T) { assert!(!contains_nul(&extension)); - // borrowck causes problems here too - let val = { - match self.filename() { - None => None, - Some(name) => { - let dot = '.' as u8; - match name.rposition_elem(&dot) { - None | Some(0) => { - if extension.container_as_bytes().is_empty() { - None - } else { - let mut v; - let extension = extension.container_as_bytes(); - v = slice::with_capacity(name.len() + extension.len() + 1); - v.push_all(name); - v.push(dot); - v.push_all(extension); - Some(v) - } - } - Some(idx) => { - if extension.container_as_bytes().is_empty() { - Some(name.slice_to(idx).to_owned()) - } else { - let mut v; - let extension = extension.container_as_bytes(); - v = slice::with_capacity(idx + extension.len() + 1); - v.push_all(name.slice_to(idx+1)); - v.push_all(extension); - Some(v) - } - } - } + + let val = self.filename().and_then(|name| { + let dot = '.' as u8; + 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()), + (idx, extlen) => { + let idx = match idx { + None | Some(0) => name.len(), + Some(val) => val + }; + + let mut v; + v = slice::with_capacity(idx + extlen + 1); + v.push_all(name.slice_to(idx)); + v.push(dot); + v.push_all(extension.container_as_bytes()); + Some(v) } } - }; + }); + match val { None => (), Some(v) => unsafe { self.set_filename_unchecked(v) }