Support converting non-utf8 paths to CFURLs

This commit is contained in:
Jeff Muizelaar
2017-10-19 18:14:23 -04:00
parent b9245f7e9b
commit a6dc32cf50
2 changed files with 31 additions and 6 deletions
+1 -1
View File
@@ -130,7 +130,7 @@ extern {
/* Getting URL Properties */
//fn CFURLGetBaseURL(anURL: CFURLRef) -> CFURLRef;
//fn CFURLGetBytes
pub fn CFURLGetBytes(anURL: CFURLRef, buffer: *mut u8, bufferLength: CFIndex) -> CFIndex;
//fn CFURLGetByteRangeForComponent
pub fn CFURLGetTypeID() -> CFTypeID;
//fn CFURLResourceIsReachable
+30 -5
View File
@@ -19,6 +19,9 @@ use std::fmt;
use std::ptr;
use std::path::Path;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
pub struct CFURL(CFURLRef);
impl Drop for CFURL {
@@ -43,13 +46,23 @@ impl fmt::Debug for CFURL {
impl CFURL {
pub fn from_path<P: AsRef<Path>>(path: P, isDirectory: bool) -> Option<CFURL> {
let path = match path.as_ref().to_str() {
Some(path) => path,
None => return None,
};
let path_bytes;
#[cfg(unix)]
{
path_bytes = path.as_ref().as_os_str().as_bytes()
}
#[cfg(not(unix))]
{
// XXX: Getting non-valid UTF8 paths into CoreFoundation on Windows is going to be unpleasant
// CFURLGetWideFileSystemRepresentation might help
path_bytes = match path.as_ref().to_str() {
Some(path) => path,
None => return None,
}
}
unsafe {
let url_ref = CFURLCreateFromFileSystemRepresentation(ptr::null_mut(), path.as_ptr(), path.len() as CFIndex, isDirectory as u8);
let url_ref = CFURLCreateFromFileSystemRepresentation(ptr::null_mut(), path_bytes.as_ptr(), path_bytes.len() as CFIndex, isDirectory as u8);
if url_ref.is_null() {
return None;
}
@@ -91,6 +104,18 @@ fn file_url_from_path() {
assert_eq!(cfurl.get_string().to_string(), "file:///usr/local/foo/");
}
#[cfg(unix)]
#[test]
fn non_utf8() {
use std::ffi::OsStr;
let path = b"/\xC0/blame";
let cfurl = CFURL::from_path(OsStr::from_bytes(path), false);
assert!(cfurl.is_some());
let len = unsafe { CFURLGetBytes(cfurl.unwrap().as_concrete_TypeRef(), ptr::null_mut(), 0) };
assert_eq!(len, 17);
}
#[test]
fn absolute_file_url() {
use core_foundation_sys::url::CFURLCreateWithFileSystemPathRelativeToBase;