diff --git a/third_party/rust/core-foundation-sys/.cargo-checksum.json b/third_party/rust/core-foundation-sys/.cargo-checksum.json index eebf04b42fbe..2002e4f2f8df 100644 --- a/third_party/rust/core-foundation-sys/.cargo-checksum.json +++ b/third_party/rust/core-foundation-sys/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"77d394e2185996b9c2478c670a7aed78fa872e61585a838ac2b93109a338813d","build.rs":"9433ed3b20cc99e716dda4c6d8507c29bc04882544cbbea8d4e48ba80fd0fa12","src/array.rs":"d648ed8cf0ccb72c3ca0d9e018a3db804edad9685739eba13f8f515e04f3708b","src/base.rs":"c995d91c9e5aed99ea28fc75561cfd573f5e8ff806ef512194e7b616c35c308f","src/bundle.rs":"1b6df1e2a112c1965c5b5ae095634444b771eb078e78bc5b251714b9ccc3d8e0","src/data.rs":"21e968951fe56e080d33474f4438de2dfb7e0c8af426a6dfb100efdd6c530eec","src/date.rs":"f6cdcb94658fafc5bacb83cfbd20ad97502b8ddf6bd1c0c0d6a2545a4f7b7420","src/dictionary.rs":"97c40c1afc719b970968179112ad76c3c89b6b4eb4ea18f7ac3f059d98cce736","src/error.rs":"61bc31a401ec6c8495668175eade9284e257da056fc666af74a5555af5daf33f","src/lib.rs":"0a061fa3866fb98568dc5307b68297819853d0737ab07ff2b515910f1ff5afaa","src/messageport.rs":"59ba92ca90bb9b3162b6df44188fac18cd979250f33a52361144c902e86529bd","src/number.rs":"0fc5598a0498baa70d64891d96522be58802a0ec18eb6f9570e0b154eb0a564c","src/propertylist.rs":"cc2b27f8f8ebc80c03871b7b1ad50ee348539b016078ce721c86b8cd5f9d75bd","src/runloop.rs":"7feab3bbb9913c3b40285bc37b920f9fe4d937d1db08d8ae69a2ec9597713598","src/set.rs":"22055b5ce6a2ce37847ee955f5e6e517348a351770d335373704776bc5412b9f","src/string.rs":"27b92e8e5d3fc95a521dc6447ccfefd9eb28ec5f42bd8571defd124d950b133f","src/url.rs":"bd965da3db23ef0e14ae196511b4ece88a3de8bbdf3e9dd58e224959f10b07ae"},"package":"bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387"} \ No newline at end of file +{"files":{"Cargo.toml":"25d7d7f3e09bad757c9ae1de8933fe75265990d0969bd92435934ff06d85e318","build.rs":"9433ed3b20cc99e716dda4c6d8507c29bc04882544cbbea8d4e48ba80fd0fa12","src/array.rs":"c70be1c0485612ac327a4fc9ca87098034e13df80dead23167560a38471fb823","src/base.rs":"d2b0474725a28731ac29bedb657c1382f100b47a8b3078bee1bee9ace6060411","src/bundle.rs":"1b6df1e2a112c1965c5b5ae095634444b771eb078e78bc5b251714b9ccc3d8e0","src/data.rs":"21e968951fe56e080d33474f4438de2dfb7e0c8af426a6dfb100efdd6c530eec","src/date.rs":"90f29b07d3bd1549a3ab64adaaf153aff5ba546c1cd449f7248479d26bce9687","src/dictionary.rs":"35a9e190eb8c81bc923cabf8da869c8d69249d911108f173bd936f2fe06804cd","src/error.rs":"61bc31a401ec6c8495668175eade9284e257da056fc666af74a5555af5daf33f","src/lib.rs":"74737fc5bd7ffc7a2e6446363aaf94909492d0d3163408c9d12c5fd8ac3bfd65","src/messageport.rs":"59ba92ca90bb9b3162b6df44188fac18cd979250f33a52361144c902e86529bd","src/number.rs":"4e69c688f24a1226fb40faec7d18861b5a617afcedbb352331c45a8e4eff292a","src/propertylist.rs":"cc2b27f8f8ebc80c03871b7b1ad50ee348539b016078ce721c86b8cd5f9d75bd","src/runloop.rs":"7feab3bbb9913c3b40285bc37b920f9fe4d937d1db08d8ae69a2ec9597713598","src/set.rs":"22055b5ce6a2ce37847ee955f5e6e517348a351770d335373704776bc5412b9f","src/string.rs":"0e9373c6e48c97d7cbdb2ceaa07bc0af4e5d25ab0f91b138b4f8667cff337f4e","src/timezone.rs":"6711924b967d96ba88be4976cf17dfd3f9573033115da8e61ad07e8b0f26cdb7","src/url.rs":"b85110fe203c685719ba92517ff3c09ce0fe358e15380ecc0bd18356ac3573ed","src/uuid.rs":"e591e0bac875832acc15ea7ee0c9bff296543f4f77470101de0602ee69c2e527"},"package":"152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5"} \ No newline at end of file diff --git a/third_party/rust/core-foundation-sys/Cargo.toml b/third_party/rust/core-foundation-sys/Cargo.toml index a4d63964c02e..68160623b974 100644 --- a/third_party/rust/core-foundation-sys/Cargo.toml +++ b/third_party/rust/core-foundation-sys/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "core-foundation-sys" -version = "0.4.4" +version = "0.4.6" authors = ["The Servo Project Developers"] build = "build.rs" description = "Bindings to Core Foundation for OS X" diff --git a/third_party/rust/core-foundation-sys/src/array.rs b/third_party/rust/core-foundation-sys/src/array.rs index 2574ecae42f6..8b0ef29806c0 100644 --- a/third_party/rust/core-foundation-sys/src/array.rs +++ b/third_party/rust/core-foundation-sys/src/array.rs @@ -9,19 +9,13 @@ use libc::c_void; -use base::{CFRange, CFIndex, CFAllocatorRef, CFTypeID}; +use base::{CFRange, CFIndex, CFAllocatorRef, CFTypeID, Boolean}; +use string::CFStringRef; -/// FIXME(pcwalton): This is wrong. -pub type CFArrayRetainCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayReleaseCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayCopyDescriptionCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayEqualCallBack = *const u8; +pub type CFArrayRetainCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void) -> *const c_void; +pub type CFArrayReleaseCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void); +pub type CFArrayCopyDescriptionCallBack = extern "C" fn(value: *const c_void) -> CFStringRef; +pub type CFArrayEqualCallBack = extern "C" fn(value1: *const c_void, value2: *const c_void) -> Boolean; #[repr(C)] #[derive(Clone, Copy)] diff --git a/third_party/rust/core-foundation-sys/src/base.rs b/third_party/rust/core-foundation-sys/src/base.rs index 42e2946120b1..2d63d8bf4aac 100644 --- a/third_party/rust/core-foundation-sys/src/base.rs +++ b/third_party/rust/core-foundation-sys/src/base.rs @@ -7,7 +7,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::cmp::Ordering; use libc::{c_uint, c_long, c_ulong, c_void, c_int}; +use string::CFStringRef; pub type Boolean = u8; pub type CFIndex = c_long; @@ -21,6 +23,24 @@ pub type CFOptionFlags = u32; pub type OSStatus = i32; pub type SInt32 = c_int; +#[repr(i64)] +#[derive(Clone, Copy)] +pub enum CFComparisonResult { + LessThan = -1, + EqualTo = 0, + GreaterThan = 1, +} + +impl Into for CFComparisonResult { + fn into(self) -> Ordering { + match self { + CFComparisonResult::LessThan => Ordering::Less, + CFComparisonResult::EqualTo => Ordering::Equal, + CFComparisonResult::GreaterThan => Ordering::Greater + } + } +} + #[repr(C)] #[derive(Clone, Copy)] pub struct CFRange { @@ -38,13 +58,35 @@ impl CFRange { } } +pub type CFAllocatorRetainCallBack = extern "C" fn(info: *mut c_void) -> *mut c_void; +pub type CFAllocatorReleaseCallBack = extern "C" fn(info: *mut c_void); +pub type CFAllocatorCopyDescriptionCallBack = extern "C" fn(info: *mut c_void) -> CFStringRef; +pub type CFAllocatorAllocateCallBack = extern "C" fn(allocSize: CFIndex, hint: CFOptionFlags, info: *mut c_void) -> *mut c_void; +pub type CFAllocatorReallocateCallBack = extern "C" fn(ptr: *mut c_void, newsize: CFIndex, hint: CFOptionFlags, info: *mut c_void) -> *mut c_void; +pub type CFAllocatorDeallocateCallBack = extern "C" fn(ptr: *mut c_void, info: *mut c_void); +pub type CFAllocatorPreferredSizeCallBack = extern "C" fn(size: CFIndex, hint: CFOptionFlags, info: *mut c_void) -> CFIndex; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFAllocatorContext { + pub version: CFIndex, + pub info: *mut c_void, + pub retain: CFAllocatorRetainCallBack, + pub release: CFAllocatorReleaseCallBack, + pub copyDescription: CFAllocatorCopyDescriptionCallBack, + pub allocate: CFAllocatorAllocateCallBack, + pub reallocate: CFAllocatorReallocateCallBack, + pub deallocate: CFAllocatorDeallocateCallBack, + pub preferredSize: CFAllocatorPreferredSizeCallBack +} + extern { /* * CFBase.h */ /* CFAllocator Reference */ - // N.B. Many CFAllocator functions and constants are omitted here. + pub static kCFAllocatorDefault: CFAllocatorRef; pub static kCFAllocatorSystemDefault: CFAllocatorRef; pub static kCFAllocatorMalloc: CFAllocatorRef; @@ -52,16 +94,25 @@ extern { pub static kCFAllocatorNull: CFAllocatorRef; pub static kCFAllocatorUseContext: CFAllocatorRef; + pub fn CFAllocatorCreate(allocator: CFAllocatorRef, context: *mut CFAllocatorContext) -> CFAllocatorRef; + pub fn CFAllocatorAllocate(allocator: CFAllocatorRef, size: CFIndex, hint: CFOptionFlags) -> *mut c_void; + pub fn CFAllocatorDeallocate(allocator: CFAllocatorRef, ptr: *mut c_void); + pub fn CFAllocatorGetPreferredSizeForSize(allocator: CFAllocatorRef, size: CFIndex, hint: CFOptionFlags) -> CFIndex; + pub fn CFAllocatorReallocate(allocator: CFAllocatorRef, ptr: *mut c_void, newsize: CFIndex, hint: CFOptionFlags) -> *mut c_void; + pub fn CFAllocatorGetDefault() -> CFAllocatorRef; + pub fn CFAllocatorSetDefault(allocator: CFAllocatorRef); + pub fn CFAllocatorGetContext(allocator: CFAllocatorRef, context: *mut CFAllocatorContext); + pub fn CFAllocatorGetTypeID() -> CFTypeID; + /* CFNull Reference */ pub static kCFNull: CFNullRef; /* CFType Reference */ - //fn CFCopyDescription //fn CFCopyTypeIDDescription - //fn CFEqual //fn CFGetAllocator + pub fn CFCopyDescription(cf: CFTypeRef) -> CFStringRef; pub fn CFEqual(cf1: CFTypeRef, cf2: CFTypeRef) -> Boolean; pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex; pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID; diff --git a/third_party/rust/core-foundation-sys/src/date.rs b/third_party/rust/core-foundation-sys/src/date.rs index c6cac2d9542c..6ae91f2ebc14 100644 --- a/third_party/rust/core-foundation-sys/src/date.rs +++ b/third_party/rust/core-foundation-sys/src/date.rs @@ -7,9 +7,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use libc::c_void; + +use base::{CFAllocatorRef, CFComparisonResult, CFTypeID}; + +#[repr(C)] +pub struct __CFDate(c_void); + +pub type CFDateRef = *const __CFDate; + pub type CFTimeInterval = f64; pub type CFAbsoluteTime = CFTimeInterval; extern { + pub static kCFAbsoluteTimeIntervalSince1904: CFTimeInterval; + pub static kCFAbsoluteTimeIntervalSince1970: CFTimeInterval; + pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime; + + pub fn CFDateCreate(allocator: CFAllocatorRef, at: CFAbsoluteTime) -> CFDateRef; + pub fn CFDateGetAbsoluteTime(date: CFDateRef) -> CFAbsoluteTime; + pub fn CFDateGetTimeIntervalSinceDate(date: CFDateRef, other: CFDateRef) -> CFTimeInterval; + pub fn CFDateCompare(date: CFDateRef, other: CFDateRef, context: *mut c_void) -> CFComparisonResult; + + pub fn CFDateGetTypeID() -> CFTypeID; } diff --git a/third_party/rust/core-foundation-sys/src/dictionary.rs b/third_party/rust/core-foundation-sys/src/dictionary.rs index bf51bb101c3b..6626cffebd7d 100644 --- a/third_party/rust/core-foundation-sys/src/dictionary.rs +++ b/third_party/rust/core-foundation-sys/src/dictionary.rs @@ -9,18 +9,17 @@ use libc::{c_void}; -use base::{CFAllocatorRef, CFIndex, CFTypeID, Boolean}; +use base::{CFAllocatorRef, CFHashCode, CFIndex, CFTypeID, Boolean}; +use string::CFStringRef; -pub type CFDictionaryApplierFunction = extern "C" fn (key: *const c_void, - value: *const c_void, - context: *mut c_void); -pub type CFDictionaryCopyDescriptionCallBack = *const u8; -pub type CFDictionaryEqualCallBack = *const u8; -pub type CFDictionaryHashCallBack = *const u8; -pub type CFDictionaryReleaseCallBack = *const u8; -pub type CFDictionaryRetainCallBack = *const u8; +pub type CFDictionaryApplierFunction = extern "C" fn(key: *const c_void, value: *const c_void, context: *mut c_void); + +pub type CFDictionaryRetainCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void) -> *const c_void; +pub type CFDictionaryReleaseCallBack = extern "C" fn(allocator: CFAllocatorRef, value: *const c_void); +pub type CFDictionaryCopyDescriptionCallBack = extern "C" fn(value: *const c_void) -> CFStringRef; +pub type CFDictionaryEqualCallBack = extern "C" fn(value1: *const c_void, value2: *const c_void) -> Boolean; +pub type CFDictionaryHashCallBack = extern "C" fn(value: *const c_void) -> CFHashCode; -#[allow(dead_code)] #[repr(C)] #[derive(Clone, Copy)] pub struct CFDictionaryKeyCallBacks { @@ -32,7 +31,6 @@ pub struct CFDictionaryKeyCallBacks { pub hash: CFDictionaryHashCallBack } -#[allow(dead_code)] #[repr(C)] #[derive(Clone, Copy)] pub struct CFDictionaryValueCallBacks { diff --git a/third_party/rust/core-foundation-sys/src/lib.rs b/third_party/rust/core-foundation-sys/src/lib.rs index 96c0b1e69014..d2744e2a0c8a 100644 --- a/third_party/rust/core-foundation-sys/src/lib.rs +++ b/third_party/rust/core-foundation-sys/src/lib.rs @@ -25,4 +25,6 @@ pub mod propertylist; pub mod runloop; pub mod set; pub mod string; +pub mod timezone; pub mod url; +pub mod uuid; diff --git a/third_party/rust/core-foundation-sys/src/number.rs b/third_party/rust/core-foundation-sys/src/number.rs index 3a5c09f428d8..8ea0d286dd32 100644 --- a/third_party/rust/core-foundation-sys/src/number.rs +++ b/third_party/rust/core-foundation-sys/src/number.rs @@ -9,7 +9,7 @@ use libc::c_void; -use base::{CFAllocatorRef, CFTypeID}; +use base::{CFAllocatorRef, CFTypeID, CFComparisonResult}; #[repr(C)] pub struct __CFBoolean(c_void); @@ -23,7 +23,7 @@ pub type CFNumberType = u32; // static kCFNumberSInt16Type: CFNumberType = 2; pub static kCFNumberSInt32Type: CFNumberType = 3; pub static kCFNumberSInt64Type: CFNumberType = 4; -// static kCFNumberFloat32Type: CFNumberType = 5; +pub static kCFNumberFloat32Type: CFNumberType = 5; pub static kCFNumberFloat64Type: CFNumberType = 6; // static kCFNumberCharType: CFNumberType = 7; // static kCFNumberShortType: CFNumberType = 8; @@ -55,6 +55,6 @@ extern { -> CFNumberRef; //fn CFNumberGetByteSize pub fn CFNumberGetValue(number: CFNumberRef, theType: CFNumberType, valuePtr: *mut c_void) -> bool; - //fn CFNumberCompare + pub fn CFNumberCompare(date: CFNumberRef, other: CFNumberRef, context: *mut c_void) -> CFComparisonResult; pub fn CFNumberGetTypeID() -> CFTypeID; } diff --git a/third_party/rust/core-foundation-sys/src/string.rs b/third_party/rust/core-foundation-sys/src/string.rs index 6095bca8711b..bdb1be704d1e 100644 --- a/third_party/rust/core-foundation-sys/src/string.rs +++ b/third_party/rust/core-foundation-sys/src/string.rs @@ -209,8 +209,7 @@ extern { bytes: *const u8, numBytes: CFIndex, encoding: CFStringEncoding, - isExternalRepresentation: Boolean, - contentsDeallocator: CFAllocatorRef) + isExternalRepresentation: Boolean) -> CFStringRef; pub fn CFStringCreateWithBytesNoCopy(alloc: CFAllocatorRef, bytes: *const u8, diff --git a/third_party/rust/core-foundation-sys/src/timezone.rs b/third_party/rust/core-foundation-sys/src/timezone.rs new file mode 100644 index 000000000000..0376974bad1b --- /dev/null +++ b/third_party/rust/core-foundation-sys/src/timezone.rs @@ -0,0 +1,27 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use base::{CFAllocatorRef, CFTypeID}; +use date::{CFTimeInterval, CFAbsoluteTime}; + +#[repr(C)] +pub struct __CFTimeZone(c_void); + +pub type CFTimeZoneRef = *const __CFTimeZone; + +extern { + pub fn CFTimeZoneCopySystem() -> CFTimeZoneRef; + pub fn CFTimeZoneCopyDefault() -> CFTimeZoneRef; + pub fn CFTimeZoneCreateWithTimeIntervalFromGMT(allocator: CFAllocatorRef, interval: CFTimeInterval) -> CFTimeZoneRef; + pub fn CFTimeZoneGetSecondsFromGMT(tz: CFTimeZoneRef, time: CFAbsoluteTime) -> CFTimeInterval; + + pub fn CFTimeZoneGetTypeID() -> CFTypeID; +} diff --git a/third_party/rust/core-foundation-sys/src/url.rs b/third_party/rust/core-foundation-sys/src/url.rs index 3081ec2e994e..bb141ad4b2aa 100644 --- a/third_party/rust/core-foundation-sys/src/url.rs +++ b/third_party/rust/core-foundation-sys/src/url.rs @@ -124,13 +124,14 @@ extern { //fn CFURLCreateStringByAddingPercentEscapes //fn CFURLCreateStringByReplacingPercentEscapes //fn CFURLCreateStringByReplacingPercentEscapesUsingEncoding - //fn CFURLGetFileSystemRepresentation + pub fn CFURLGetFileSystemRepresentation(anURL: CFURLRef, resolveAgainstBase: Boolean, buffer: *mut u8, maxBufLen: CFIndex) -> Boolean; + //fn CFURLGetFSRef pub fn CFURLGetString(anURL: CFURLRef) -> CFStringRef; /* 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 diff --git a/third_party/rust/core-foundation-sys/src/uuid.rs b/third_party/rust/core-foundation-sys/src/uuid.rs new file mode 100644 index 000000000000..63c180fa13e5 --- /dev/null +++ b/third_party/rust/core-foundation-sys/src/uuid.rs @@ -0,0 +1,48 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +use libc::c_void; + +use base::{CFAllocatorRef, CFTypeID}; + +#[repr(C)] +pub struct __CFUUID(c_void); + +pub type CFUUIDRef = *const __CFUUID; + +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct CFUUIDBytes { + pub byte0: u8, + pub byte1: u8, + pub byte2: u8, + pub byte3: u8, + pub byte4: u8, + pub byte5: u8, + pub byte6: u8, + pub byte7: u8, + pub byte8: u8, + pub byte9: u8, + pub byte10: u8, + pub byte11: u8, + pub byte12: u8, + pub byte13: u8, + pub byte14: u8, + pub byte15: u8 +} + +extern { + /* + * CFUUID.h + */ + pub fn CFUUIDCreate(allocator: CFAllocatorRef) -> CFUUIDRef; + pub fn CFUUIDCreateFromUUIDBytes(allocator: CFAllocatorRef, bytes: CFUUIDBytes) -> CFUUIDRef; + pub fn CFUUIDGetUUIDBytes(uuid: CFUUIDRef) -> CFUUIDBytes; + + pub fn CFUUIDGetTypeID() -> CFTypeID; +} diff --git a/third_party/rust/core-foundation/.cargo-checksum.json b/third_party/rust/core-foundation/.cargo-checksum.json index a78d579930e0..3bafb95716e0 100644 --- a/third_party/rust/core-foundation/.cargo-checksum.json +++ b/third_party/rust/core-foundation/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"309020bd517f30f6daaf95caf2a832118eb3cd23d5732d076e059a7a8f4dea49","src/array.rs":"ceeb3298fb939ead81914a0e6a555098e59f97c47e62adb625273bde2bb299a4","src/base.rs":"540c85a6600503e2bdf34087e7e921615b094f7493099c7e319c76f34ab97a02","src/boolean.rs":"112adb640ded232cba59eb27edafcf4a3c045cca6f4b0ecb53bb48b741c2139a","src/bundle.rs":"69fa69ec2d8ea8e897363e2351d947235d040eaa5f5ff562e280e59399f56769","src/data.rs":"fc44b08e644b66ae471bb7c8141ec6be7cf5f35eb985dbca5924668a67f0efe5","src/dictionary.rs":"0f3129629db02ea233d08fd937e8290c40f401d644f6a8afc13717094a767559","src/error.rs":"0edbf66bcaa8a68f1de77b9056696b6be4f2dc773f4561f4279e6494cc38453a","src/lib.rs":"71ee7a83a7012138b5a86897f5617d2742c668ccc69664a8c5b4cf080486ddd8","src/number.rs":"262db248c88ac08a3d28d0940ef25fe796fd4ebcf1eeea7bb8a6caa3abdc97f9","src/propertylist.rs":"ec814aa190bc6cf8c2bb3f2d5c65e1a706a770701c8589d29fc01bddad6a11c6","src/runloop.rs":"6fdc656958950ff84a167c67111e94818246caa50e2ba84004853f28652490d6","src/set.rs":"f98fbd31b107f27680727676ab7a3725d6b4370f428e58759ca680eb339a5ea3","src/string.rs":"ec5420a3916e5ebd2cc487ffc605d8fe8de7d09cae8c9fecbf20aa21595f4bee","src/url.rs":"2b3caaea223bc27fb268a81f0607b975f92b9df9a58194ac1881dacf314e4219"},"package":"5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7"} \ No newline at end of file +{"files":{"Cargo.toml":"2e10fc485f55e677435630e84c40ea2d6c43819b861982dfb54e5e9d75662cf7","src/array.rs":"dda1a99634934f215e522a4add77e1fcf286249cbe26b44353676281bb3e060a","src/base.rs":"4142d73825fd273fb693756adc93fb3758bc6fc628d2aad3635c7544e447e148","src/boolean.rs":"809f988f45178056682379ec6a2f5f279bdc721e97b8a313118eadc82a36ffb1","src/bundle.rs":"69fa69ec2d8ea8e897363e2351d947235d040eaa5f5ff562e280e59399f56769","src/data.rs":"66dd852ef988dc4f996b18bb1e3e9cb17143e5bb1312e38d209fb728a53f8881","src/date.rs":"b4f562487baa53522071a574c53e80337067be0ca678a5dcf3c4e15d65341627","src/dictionary.rs":"31a1d2fd20ced092df127cb72472a6545344852723a3e922fc7ac0071ec994ee","src/error.rs":"0edbf66bcaa8a68f1de77b9056696b6be4f2dc773f4561f4279e6494cc38453a","src/lib.rs":"47b11c4119aedf01c4b1fb1b391820de6edd4560b45bef7edc6f328b1bc3f588","src/number.rs":"12d3ef89e9e5c2c077b7c3c426fce0249d7fa936dcea75f129b1455699469643","src/propertylist.rs":"e87ca9556b94bfc25fa859994a2d84e8c627c78a9ba628fa4a02998b84eaf04e","src/runloop.rs":"ed161c100f950d59d218bacb79d47aa51481d9614d6261bb4915464f8f74d210","src/set.rs":"6fd12fbbc97b1fb8bdbd934b979c9b081613d14e5f6e85a63cd4d9326ba0bda4","src/string.rs":"4a117f4080b3b953076644d9b102e60d72c31d3a4cfa8bd17d714d5c79844281","src/timezone.rs":"afab0cc4815936d39966bc96e07f5bf2709e5fbc2f18f8361ae6c70fda204e84","src/url.rs":"2d4bcd40ea6717484af878700ec6385bb408357ecee460dbe8b6c8bf48b733f2","src/uuid.rs":"0f0898044cd4187e4b6ee1d0f170d974c0251280fab466c8adf348cb49c42577"},"package":"8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e"} \ No newline at end of file diff --git a/third_party/rust/core-foundation/Cargo.toml b/third_party/rust/core-foundation/Cargo.toml index b20557ccc8a0..6c3ff250afb9 100644 --- a/third_party/rust/core-foundation/Cargo.toml +++ b/third_party/rust/core-foundation/Cargo.toml @@ -12,18 +12,28 @@ [package] name = "core-foundation" -version = "0.4.4" +version = "0.4.6" authors = ["The Servo Project Developers"] description = "Bindings to Core Foundation for OS X" homepage = "https://github.com/servo/core-foundation-rs" license = "MIT / Apache-2.0" repository = "https://github.com/servo/core-foundation-rs" +[dependencies.chrono] +version = "0.4" +optional = true + +[dependencies.core-foundation-sys] +version = "0.4.6" + [dependencies.libc] version = "0.2" -[dependencies.core-foundation-sys] -version = "0.4.4" +[dependencies.uuid] +version = "0.5" +optional = true [features] -mac_os_10_8_features = ["core-foundation-sys/mac_os_10_8_features"] mac_os_10_7_support = ["core-foundation-sys/mac_os_10_7_support"] +mac_os_10_8_features = ["core-foundation-sys/mac_os_10_8_features"] +with-chrono = ["chrono"] +with-uuid = ["uuid"] diff --git a/third_party/rust/core-foundation/src/array.rs b/third_party/rust/core-foundation/src/array.rs index 3859b0a5b0f6..e681c682f49e 100644 --- a/third_party/rust/core-foundation/src/array.rs +++ b/third_party/rust/core-foundation/src/array.rs @@ -12,15 +12,40 @@ pub use core_foundation_sys::array::*; pub use core_foundation_sys::base::{CFIndex, CFRelease}; use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; +use base::CFType; use libc::c_void; use std::mem; +use std::marker::PhantomData; use base::{CFIndexConvertible, TCFType, CFRange}; /// A heterogeneous immutable array. -pub struct CFArray(CFArrayRef); +pub struct CFArray(CFArrayRef, PhantomData); -impl Drop for CFArray { +/// A trait describing how to convert from the stored *const c_void to the desired T +pub unsafe trait FromVoid { + unsafe fn from_void(x: *const c_void) -> Self; +} + +unsafe impl FromVoid for u32 { + unsafe fn from_void(x: *const c_void) -> u32 { + x as usize as u32 + } +} + +unsafe impl FromVoid for *const c_void { + unsafe fn from_void(x: *const c_void) -> *const c_void { + x + } +} + +unsafe impl FromVoid for CFType { + unsafe fn from_void(x: *const c_void) -> CFType { + TCFType::wrap_under_get_rule(mem::transmute(x)) + } +} + +impl Drop for CFArray { fn drop(&mut self) { unsafe { CFRelease(self.as_CFTypeRef()) @@ -28,15 +53,15 @@ impl Drop for CFArray { } } -pub struct CFArrayIterator<'a> { - array: &'a CFArray, +pub struct CFArrayIterator<'a, T: 'a> { + array: &'a CFArray, index: CFIndex, } -impl<'a> Iterator for CFArrayIterator<'a> { - type Item = *const c_void; +impl<'a, T: FromVoid> Iterator for CFArrayIterator<'a, T> { + type Item = T; - fn next(&mut self) -> Option<*const c_void> { + fn next(&mut self) -> Option { if self.index >= self.array.len() { None } else { @@ -47,11 +72,18 @@ impl<'a> Iterator for CFArrayIterator<'a> { } } -impl_TCFType!(CFArray, CFArrayRef, CFArrayGetTypeID); +impl<'a, T: FromVoid> ExactSizeIterator for CFArrayIterator<'a, T> { + fn len(&self) -> usize { + (self.array.len() - self.index) as usize + } +} -impl CFArray { +impl_TCFTypeGeneric!(CFArray, CFArrayRef, CFArrayGetTypeID); +impl_CFTypeDescriptionGeneric!(CFArray); + +impl CFArray { /// Creates a new `CFArray` with the given elements, which must be `CFType` objects. - pub fn from_CFTypes(elems: &[T]) -> CFArray where T: TCFType { + pub fn from_CFTypes(elems: &[T]) -> CFArray where T: TCFType { unsafe { let elems: Vec = elems.iter().map(|elem| elem.as_CFTypeRef()).collect(); let array_ref = CFArrayCreate(kCFAllocatorDefault, @@ -62,13 +94,22 @@ impl CFArray { } } + #[deprecated(note = "please use `as_untyped` instead")] + pub fn to_untyped(self) -> CFArray { + unsafe { CFArray::wrap_under_get_rule(self.0) } + } + + pub fn as_untyped(&self) -> CFArray { + unsafe { CFArray::wrap_under_get_rule(self.0) } + } + /// Iterates over the elements of this `CFArray`. /// /// Careful; the loop body must wrap the reference properly. Generally, when array elements are /// Core Foundation objects (not always true), they need to be wrapped with /// `TCFType::wrap_under_get_rule()`. #[inline] - pub fn iter<'a>(&'a self) -> CFArrayIterator<'a> { + pub fn iter<'a>(&'a self) -> CFArrayIterator<'a, T> { CFArrayIterator { array: self, index: 0 @@ -83,11 +124,9 @@ impl CFArray { } #[inline] - pub fn get(&self, index: CFIndex) -> *const c_void { + pub fn get(&self, index: CFIndex) -> T where T: FromVoid { assert!(index < self.len()); - unsafe { - CFArrayGetValueAtIndex(self.0, index) - } + unsafe { T::from_void(CFArrayGetValueAtIndex(self.0, index)) } } pub fn get_values(&self, range: CFRange) -> Vec<*const c_void> { @@ -107,54 +146,90 @@ impl CFArray { } } -impl<'a> IntoIterator for &'a CFArray { - type Item = *const c_void; - type IntoIter = CFArrayIterator<'a>; +impl<'a, T: FromVoid> IntoIterator for &'a CFArray { + type Item = T; + type IntoIter = CFArrayIterator<'a, T>; - fn into_iter(self) -> CFArrayIterator<'a> { + fn into_iter(self) -> CFArrayIterator<'a, T> { self.iter() } } -#[test] -fn should_box_and_unbox() { - use number::{CFNumber, number}; +#[cfg(test)] +mod tests { + use super::*; + use std::mem; - let n1 = number(1); - let n2 = number(2); - let n3 = number(3); - let n4 = number(4); - let n5 = number(5); + #[test] + fn to_untyped_correct_retain_count() { + let array = CFArray::::from_CFTypes(&[]); + assert_eq!(array.retain_count(), 1); - let arr = CFArray::from_CFTypes(&[ - n1.as_CFType(), - n2.as_CFType(), - n3.as_CFType(), - n4.as_CFType(), - n5.as_CFType(), - ]); + let untyped_array = array.to_untyped(); + assert_eq!(untyped_array.retain_count(), 1); + } - assert!(arr.get_all_values() == &[n1.as_CFTypeRef(), - n2.as_CFTypeRef(), - n3.as_CFTypeRef(), - n4.as_CFTypeRef(), - n5.as_CFTypeRef()]); + #[test] + fn as_untyped_correct_retain_count() { + let array = CFArray::::from_CFTypes(&[]); + assert_eq!(array.retain_count(), 1); - unsafe { - let mut sum = 0; + let untyped_array = array.as_untyped(); + assert_eq!(array.retain_count(), 2); + assert_eq!(untyped_array.retain_count(), 2); - for elem in arr.iter() { - let number: CFNumber = TCFType::wrap_under_get_rule(mem::transmute(elem)); - sum += number.to_i64().unwrap() + mem::drop(array); + assert_eq!(untyped_array.retain_count(), 1); + } + + #[test] + fn should_box_and_unbox() { + use number::CFNumber; + + let n0 = CFNumber::from(0); + let n1 = CFNumber::from(1); + let n2 = CFNumber::from(2); + let n3 = CFNumber::from(3); + let n4 = CFNumber::from(4); + let n5 = CFNumber::from(5); + + let arr = CFArray::from_CFTypes(&[ + n0.as_CFType(), + n1.as_CFType(), + n2.as_CFType(), + n3.as_CFType(), + n4.as_CFType(), + n5.as_CFType(), + ]); + + assert!(arr.get_all_values() == &[n0.as_CFTypeRef(), + n1.as_CFTypeRef(), + n2.as_CFTypeRef(), + n3.as_CFTypeRef(), + n4.as_CFTypeRef(), + n5.as_CFTypeRef()]); + + unsafe { + let mut sum = 0; + + let mut iter = arr.iter(); + assert_eq!(iter.len(), 6); + assert!(iter.next().is_some()); + assert_eq!(iter.len(), 5); + + for elem in iter { + let number: CFNumber = TCFType::wrap_under_get_rule(mem::transmute(elem)); + sum += number.to_i64().unwrap() + } + + assert!(sum == 15); + + for elem in arr.iter() { + let number: CFNumber = TCFType::wrap_under_get_rule(mem::transmute(elem)); + sum += number.to_i64().unwrap() + } + + assert!(sum == 30); } - - assert!(sum == 15); - - for elem in arr.iter() { - let number: CFNumber = TCFType::wrap_under_get_rule(mem::transmute(elem)); - sum += number.to_i64().unwrap() - } - - assert!(sum == 30); } } diff --git a/third_party/rust/core-foundation/src/base.rs b/third_party/rust/core-foundation/src/base.rs index 3f4bcea169f2..3d945e976675 100644 --- a/third_party/rust/core-foundation/src/base.rs +++ b/third_party/rust/core-foundation/src/base.rs @@ -7,8 +7,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::fmt; + pub use core_foundation_sys::base::*; +use string::CFString; + pub trait CFIndexConvertible { /// Always use this method to construct a `CFIndex` value. It performs bounds checking to /// ensure the value is in range. @@ -29,6 +33,15 @@ impl CFIndexConvertible for usize { /// Superclass of all Core Foundation objects. pub struct CFType(CFTypeRef); +impl fmt::Debug for CFType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let desc = unsafe { + CFString::wrap_under_create_rule(CFCopyDescription(self.0)) + }; + desc.fmt(f) + } +} + impl Clone for CFType { #[inline] fn clone(&self) -> CFType { @@ -38,6 +51,15 @@ impl Clone for CFType { } } +impl PartialEq for CFType { + #[inline] + fn eq(&self, other: &CFType) -> bool { + unsafe { + CFEqual(self.as_CFTypeRef(), other.as_CFTypeRef()) != 0 + } + } +} + impl Drop for CFType { fn drop(&mut self) { unsafe { @@ -46,6 +68,29 @@ impl Drop for CFType { } } +/// An allocator for Core Foundation objects. +pub struct CFAllocator(CFAllocatorRef); + +impl Drop for CFAllocator { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFAllocator, CFAllocatorRef, CFAllocatorGetTypeID); + +impl CFAllocator { + #[inline] + pub fn new(mut context: CFAllocatorContext) -> CFAllocator { + unsafe { + let allocator_ref = CFAllocatorCreate(kCFAllocatorDefault, &mut context); + TCFType::wrap_under_create_rule(allocator_ref) + } + } +} + /// All Core Foundation types implement this trait. The type parameter `TypeRef` specifies the /// associated Core Foundation type: e.g. for `CFType` this is `CFTypeRef`; for `CFArray` this is /// `CFArrayRef`. @@ -133,10 +178,20 @@ impl TCFType for CFType { // FIXME(pcwalton): Is this right? 0 } +} - #[inline] - fn instance_of>(&self) -> bool { - // Since this is the root of the type hierarchy, we always answer yes. - true + +#[cfg(test)] +mod tests { + use super::*; + use boolean::CFBoolean; + + #[test] + fn cftype_instance_of() { + let string = CFString::from_static_string("foo"); + let cftype = string.as_CFType(); + + assert!(cftype.instance_of::<_, CFString>()); + assert!(!cftype.instance_of::<_, CFBoolean>()); } } diff --git a/third_party/rust/core-foundation/src/boolean.rs b/third_party/rust/core-foundation/src/boolean.rs index 8e6ca3bf83e0..e84346770153 100644 --- a/third_party/rust/core-foundation/src/boolean.rs +++ b/third_party/rust/core-foundation/src/boolean.rs @@ -28,6 +28,7 @@ impl Drop for CFBoolean { } impl_TCFType!(CFBoolean, CFBooleanRef, CFBooleanGetTypeID); +impl_CFTypeDescription!(CFBoolean); impl CFBoolean { pub fn true_value() -> CFBoolean { @@ -42,3 +43,35 @@ impl CFBoolean { } } } + +impl From for CFBoolean { + fn from(value: bool) -> CFBoolean { + if value { + CFBoolean::true_value() + } else { + CFBoolean::false_value() + } + } +} + +impl From for bool { + fn from(value: CFBoolean) -> bool { + value.0 == unsafe { kCFBooleanTrue } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn to_and_from_bool() { + let b_false = CFBoolean::from(false); + let b_true = CFBoolean::from(true); + assert_ne!(b_false, b_true); + assert_eq!(b_false, CFBoolean::false_value()); + assert_eq!(b_true, CFBoolean::true_value()); + assert!(!bool::from(b_false)); + assert!(bool::from(b_true)); + } +} diff --git a/third_party/rust/core-foundation/src/data.rs b/third_party/rust/core-foundation/src/data.rs index 7d83a615c13e..baa95f2417ff 100644 --- a/third_party/rust/core-foundation/src/data.rs +++ b/third_party/rust/core-foundation/src/data.rs @@ -29,6 +29,7 @@ impl Drop for CFData { } impl_TCFType!(CFData, CFDataRef, CFDataGetTypeID); +impl_CFTypeDescription!(CFData); impl CFData { pub fn from_buffer(buffer: &[u8]) -> CFData { diff --git a/third_party/rust/core-foundation/src/date.rs b/third_party/rust/core-foundation/src/date.rs new file mode 100644 index 000000000000..ee78cf81ce01 --- /dev/null +++ b/third_party/rust/core-foundation/src/date.rs @@ -0,0 +1,136 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Core Foundation date objects. + +pub use core_foundation_sys::date::*; +use core_foundation_sys::base::{CFRelease, kCFAllocatorDefault}; + +use base::TCFType; + +#[cfg(feature = "with-chrono")] +use chrono::NaiveDateTime; + +/// A date. +pub struct CFDate(CFDateRef); + +impl Drop for CFDate { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFDate, CFDateRef, CFDateGetTypeID); +impl_CFTypeDescription!(CFDate); +impl_CFComparison!(CFDate, CFDateCompare); + +impl CFDate { + #[inline] + pub fn new(time: CFAbsoluteTime) -> CFDate { + unsafe { + let date_ref = CFDateCreate(kCFAllocatorDefault, time); + TCFType::wrap_under_create_rule(date_ref) + } + } + + #[inline] + pub fn now() -> CFDate { + CFDate::new(unsafe { CFAbsoluteTimeGetCurrent() }) + } + + #[inline] + pub fn abs_time(&self) -> CFAbsoluteTime { + unsafe { + CFDateGetAbsoluteTime(self.0) + } + } + + #[cfg(feature = "with-chrono")] + pub fn naive_utc(&self) -> NaiveDateTime { + let ts = unsafe { + self.abs_time() + kCFAbsoluteTimeIntervalSince1970 + }; + let (secs, nanos) = if ts.is_sign_positive() { + (ts.trunc() as i64, ts.fract()) + } else { + // nanoseconds can't be negative in NaiveDateTime + (ts.trunc() as i64 - 1, 1.0 - ts.fract().abs()) + }; + NaiveDateTime::from_timestamp(secs, (nanos * 1e9).floor() as u32) + } + + #[cfg(feature = "with-chrono")] + pub fn from_naive_utc(time: NaiveDateTime) -> CFDate { + let secs = time.timestamp(); + let nanos = time.timestamp_subsec_nanos(); + let ts = unsafe { + secs as f64 + (nanos as f64 / 1e9) - kCFAbsoluteTimeIntervalSince1970 + }; + CFDate::new(ts) + } +} + +#[cfg(test)] +mod test { + use super::CFDate; + use std::cmp::Ordering; + + #[cfg(feature = "with-chrono")] + use chrono::NaiveDateTime; + + #[cfg(feature = "with-chrono")] + fn approx_eq(a: f64, b: f64) -> bool { + use std::f64; + + let same_sign = a.is_sign_positive() == b.is_sign_positive(); + let equal = ((a - b).abs() / f64::min(a.abs() + b.abs(), f64::MAX)) < f64::EPSILON; + (same_sign && equal) + } + + #[test] + fn date_comparison() { + let now = CFDate::now(); + let past = CFDate::new(now.abs_time() - 1.0); + assert_eq!(now.cmp(&past), Ordering::Greater); + assert_eq!(now.cmp(&now), Ordering::Equal); + assert_eq!(past.cmp(&now), Ordering::Less); + } + + #[test] + fn date_equality() { + let now = CFDate::now(); + let same_time = CFDate::new(now.abs_time()); + assert_eq!(now, same_time); + } + + #[test] + #[cfg(feature = "with-chrono")] + fn date_chrono_conversion_positive() { + let date = CFDate::now(); + let datetime = date.naive_utc(); + let converted = CFDate::from_naive_utc(datetime); + assert!(approx_eq(date.abs_time(), converted.abs_time())); + } + + #[test] + #[cfg(feature = "with-chrono")] + fn date_chrono_conversion_negative() { + use super::kCFAbsoluteTimeIntervalSince1970; + + let ts = unsafe { + kCFAbsoluteTimeIntervalSince1970 - 420.0 + }; + let date = CFDate::new(ts); + let datetime: NaiveDateTime = date.naive_utc(); + let converted = CFDate::from_naive_utc(datetime); + assert!(approx_eq(date.abs_time(), converted.abs_time())); + } +} diff --git a/third_party/rust/core-foundation/src/dictionary.rs b/third_party/rust/core-foundation/src/dictionary.rs index 9953c4b10500..822eb9cc4a26 100644 --- a/third_party/rust/core-foundation/src/dictionary.rs +++ b/third_party/rust/core-foundation/src/dictionary.rs @@ -30,6 +30,7 @@ impl Drop for CFDictionary { } impl_TCFType!(CFDictionary, CFDictionaryRef, CFDictionaryGetTypeID); +impl_CFTypeDescription!(CFDictionary); impl CFDictionary { pub fn from_CFType_pairs(pairs: &[(K, V)]) -> CFDictionary @@ -69,6 +70,13 @@ impl CFDictionary { } } + /// Similar to `contains_key` but acts on a higher level, automatically converting from any + /// `TCFType` to the raw pointer of its concrete TypeRef. + #[inline] + pub fn contains_key2>(&self, key: &K) -> bool { + self.contains_key(key.as_concrete_TypeRef() as *const c_void) + } + #[inline] pub fn find(&self, key: *const c_void) -> Option<*const c_void> { unsafe { @@ -81,13 +89,20 @@ impl CFDictionary { } } + /// Similar to `find` but acts on a higher level, automatically converting from any `TCFType` + /// to the raw pointer of its concrete TypeRef. + #[inline] + pub fn find2>(&self, key: &K) -> Option<*const c_void> { + self.find(key.as_concrete_TypeRef() as *const c_void) + } + + /// # Panics + /// + /// Panics if the key is not present in the dictionary. Use `find` to get an `Option` instead + /// of panicking. #[inline] pub fn get(&self, key: *const c_void) -> *const c_void { - let value = self.find(key); - if value.is_none() { - panic!("No entry found for key {:p}", key); - } - value.unwrap() + self.find(key).expect(&format!("No entry found for key {:p}", key)) } /// A convenience function to retrieve `CFType` instances. diff --git a/third_party/rust/core-foundation/src/lib.rs b/third_party/rust/core-foundation/src/lib.rs index f4ca71d83f41..775cd23acd89 100644 --- a/third_party/rust/core-foundation/src/lib.rs +++ b/third_party/rust/core-foundation/src/lib.rs @@ -11,6 +11,9 @@ extern crate core_foundation_sys; extern crate libc; +#[cfg(feature = "with-chrono")] +extern crate chrono; + #[macro_export] macro_rules! impl_TCFType { ($ty:ident, $raw:ident, $ty_id:ident) => { @@ -45,6 +48,125 @@ macro_rules! impl_TCFType { } } } + + impl Clone for $ty { + #[inline] + fn clone(&self) -> $ty { + unsafe { + $ty::wrap_under_get_rule(self.0) + } + } + } + + impl PartialEq for $ty { + #[inline] + fn eq(&self, other: &$ty) -> bool { + self.as_CFType().eq(&other.as_CFType()) + } + } + + impl Eq for $ty { } + } +} + +// This is basically identical to the implementation above. I can't +// think of a clean way to have them share code +#[macro_export] +macro_rules! impl_TCFTypeGeneric { + ($ty:ident, $raw:ident, $ty_id:ident) => { + impl $crate::base::TCFType<$raw> for $ty { + #[inline] + fn as_concrete_TypeRef(&self) -> $raw { + self.0 + } + + #[inline] + unsafe fn wrap_under_get_rule(reference: $raw) -> $ty { + let reference = ::std::mem::transmute(::core_foundation_sys::base::CFRetain(::std::mem::transmute(reference))); + $crate::base::TCFType::wrap_under_create_rule(reference) + } + + #[inline] + fn as_CFTypeRef(&self) -> ::core_foundation_sys::base::CFTypeRef { + unsafe { + ::std::mem::transmute(self.as_concrete_TypeRef()) + } + } + + #[inline] + unsafe fn wrap_under_create_rule(obj: $raw) -> $ty { + $ty(obj, PhantomData) + } + + #[inline] + fn type_id() -> ::core_foundation_sys::base::CFTypeID { + unsafe { + $ty_id() + } + } + } + + impl Clone for $ty { + #[inline] + fn clone(&self) -> $ty { + unsafe { + $ty::wrap_under_get_rule(self.0) + } + } + } + + impl PartialEq for $ty { + #[inline] + fn eq(&self, other: &$ty) -> bool { + self.as_CFType().eq(&other.as_CFType()) + } + } + + impl Eq for $ty { } + } +} + +#[macro_export] +macro_rules! impl_CFTypeDescription { + ($ty:ident) => { + impl ::std::fmt::Debug for $ty { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + self.as_CFType().fmt(f) + } + } + } +} + +// The same as impl_CFTypeDescription but with a type parameter +#[macro_export] +macro_rules! impl_CFTypeDescriptionGeneric { + ($ty:ident) => { + impl ::std::fmt::Debug for $ty { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + self.as_CFType().fmt(f) + } + } + } +} + +#[macro_export] +macro_rules! impl_CFComparison { + ($ty:ident, $compare:ident) => { + impl PartialOrd for $ty { + #[inline] + fn partial_cmp(&self, other: &$ty) -> Option<::std::cmp::Ordering> { + unsafe { + Some($compare(self.as_concrete_TypeRef(), other.as_concrete_TypeRef(), ::std::ptr::null_mut()).into()) + } + } + } + + impl Ord for $ty { + #[inline] + fn cmp(&self, other: &$ty) -> ::std::cmp::Ordering { + self.partial_cmp(other).unwrap() + } + } } } @@ -52,7 +174,7 @@ pub mod array; pub mod base; pub mod boolean; pub mod data; -pub use core_foundation_sys::date; // back compat +pub mod date; pub mod dictionary; pub mod error; pub mod number; @@ -62,6 +184,8 @@ pub mod url; pub mod bundle; pub mod propertylist; pub mod runloop; +pub mod timezone; +pub mod uuid; #[cfg(test)] pub mod test { @@ -69,7 +193,7 @@ pub mod test { fn test_stuff() { use base::TCFType; use boolean::CFBoolean; - use number::number; + use number::CFNumber; use dictionary::CFDictionary; use string::CFString; @@ -82,7 +206,7 @@ pub mod test { let boo = CFString::from_static_string("Boo"); let foo = CFString::from_static_string("Foo"); let tru = CFBoolean::true_value(); - let n42 = number(42); + let n42 = CFNumber::from(42); let d = CFDictionary::from_CFType_pairs(&[ (bar.as_CFType(), boo.as_CFType()), diff --git a/third_party/rust/core-foundation/src/number.rs b/third_party/rust/core-foundation/src/number.rs index 771c75eb984c..cd02635fe42d 100644 --- a/third_party/rust/core-foundation/src/number.rs +++ b/third_party/rust/core-foundation/src/number.rs @@ -27,19 +27,10 @@ impl Drop for CFNumber { } impl_TCFType!(CFNumber, CFNumberRef, CFNumberGetTypeID); +impl_CFTypeDescription!(CFNumber); +impl_CFComparison!(CFNumber, CFNumberCompare); -// TODO(pcwalton): Floating point. impl CFNumber { - #[inline] - pub fn from_i32(value: i32) -> CFNumber { - unsafe { - let number_ref = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - mem::transmute(&value)); - TCFType::wrap_under_create_rule(number_ref) - } - } - #[inline] pub fn to_i64(&self) -> Option { unsafe { @@ -49,6 +40,15 @@ impl CFNumber { } } + #[inline] + pub fn to_f32(&self) -> Option { + unsafe { + let mut value: f32 = 0.0; + let ok = CFNumberGetValue(self.0, kCFNumberFloat32Type, mem::transmute(&mut value)); + if ok { Some(value) } else { None } + } + } + #[inline] pub fn to_f64(&self) -> Option { unsafe { @@ -58,28 +58,89 @@ impl CFNumber { } } + #[deprecated(note = "please use `CFNumber::from` instead")] + #[inline] + pub fn from_i32(value: i32) -> CFNumber { + CFNumber::from(value) + } + + #[deprecated(note = "please use `CFNumber::from` instead")] #[inline] pub fn from_i64(value: i64) -> CFNumber { + Self::from(value) + } + + #[deprecated(note = "please use `CFNumber::from` instead")] + #[inline] + pub fn from_f32(value: f32) -> CFNumber { + Self::from(value) + } + + #[deprecated(note = "please use `CFNumber::from` instead")] + #[inline] + pub fn from_f64(value: f64) -> CFNumber { + Self::from(value) + } +} + +impl From for CFNumber { + #[inline] + fn from(value: i32) -> Self { unsafe { - let number_ref = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt64Type, - mem::transmute(&value)); + let number_ref = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberSInt32Type, + mem::transmute(&value), + ); TCFType::wrap_under_create_rule(number_ref) } } +} +impl From for CFNumber { #[inline] - pub fn from_f64(value: f64) -> CFNumber { + fn from(value: i64) -> Self { unsafe { - let number_ref = CFNumberCreate(kCFAllocatorDefault, - kCFNumberFloat64Type, - mem::transmute(&value)); + let number_ref = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberSInt64Type, + mem::transmute(&value), + ); + TCFType::wrap_under_create_rule(number_ref) + } + } +} + +impl From for CFNumber { + #[inline] + fn from(value: f32) -> Self { + unsafe { + let number_ref = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberFloat32Type, + mem::transmute(&value), + ); + TCFType::wrap_under_create_rule(number_ref) + } + } +} + +impl From for CFNumber { + #[inline] + fn from(value: f64) -> Self { + unsafe { + let number_ref = CFNumberCreate( + kCFAllocatorDefault, + kCFNumberFloat64Type, + mem::transmute(&value), + ); TCFType::wrap_under_create_rule(number_ref) } } } /// A convenience function to create CFNumbers. +#[deprecated(note = "please use `CFNumber::from` instead")] pub fn number(value: i64) -> CFNumber { - CFNumber::from_i64(value) + CFNumber::from(value) } diff --git a/third_party/rust/core-foundation/src/propertylist.rs b/third_party/rust/core-foundation/src/propertylist.rs index 9b175fe4c310..b8d5e020e02d 100644 --- a/third_party/rust/core-foundation/src/propertylist.rs +++ b/third_party/rust/core-foundation/src/propertylist.rs @@ -10,16 +10,18 @@ //! Core Foundation property lists use std::ptr; +use std::mem; use libc::c_void; use error::CFError; use data::CFData; -use base::{TCFType}; +use base::{CFType, TCFType}; pub use core_foundation_sys::propertylist::*; use core_foundation_sys::error::CFErrorRef; -use core_foundation_sys::base::{kCFAllocatorDefault}; +use core_foundation_sys::base::{CFGetRetainCount, CFGetTypeID, CFIndex, CFRelease, CFRetain, + CFShow, CFTypeID, kCFAllocatorDefault}; pub fn create_with_data(data: CFData, options: CFPropertyListMutabilityOptions) @@ -56,13 +58,165 @@ pub fn create_data(property_list: *const c_void, format: CFPropertyListFormat) - } } + +/// Trait for all subclasses of [`CFPropertyList`]. +/// +/// [`CFPropertyList`]: struct.CFPropertyList.html +pub trait CFPropertyListSubClass: TCFType<*const Raw> { + /// Create an instance of the superclass type [`CFPropertyList`] for this instance. + /// + /// [`CFPropertyList`]: struct.CFPropertyList.html + fn to_CFPropertyList(&self) -> CFPropertyList { + unsafe { CFPropertyList::wrap_under_get_rule(self.as_concrete_TypeRef() as *const c_void) } + } +} + +impl CFPropertyListSubClass<::data::__CFData> for ::data::CFData {} +impl CFPropertyListSubClass<::string::__CFString> for ::string::CFString {} +impl CFPropertyListSubClass<::array::__CFArray> for ::array::CFArray {} +impl CFPropertyListSubClass<::dictionary::__CFDictionary> for ::dictionary::CFDictionary {} +impl CFPropertyListSubClass<::date::__CFDate> for ::date::CFDate {} +impl CFPropertyListSubClass<::number::__CFBoolean> for ::boolean::CFBoolean {} +impl CFPropertyListSubClass<::number::__CFNumber> for ::number::CFNumber {} + +/// A CFPropertyList struct. This is superclass to [`CFData`], [`CFString`], [`CFArray`], +/// [`CFDictionary`], [`CFDate`], [`CFBoolean`], and [`CFNumber`]. +/// +/// This superclass type does not have its own `CFTypeID`, instead each instance has the `CFTypeID` +/// of the subclass it is an instance of. Thus, this type cannot implement the [`TCFType`] trait, +/// since it cannot implement the static [`TCFType::type_id()`] method. +/// +/// [`CFData`]: ../data/struct.CFData.html +/// [`CFString`]: ../string/struct.CFString.html +/// [`CFArray`]: ../array/struct.CFArray.html +/// [`CFDictionary`]: ../dictionary/struct.CFDictionary.html +/// [`CFDate`]: ../date/struct.CFDate.html +/// [`CFBoolean`]: ../boolean/struct.CFBoolean.html +/// [`CFNumber`]: ../number/struct.CFNumber.html +/// [`TCFType`]: ../base/trait.TCFType.html +/// [`TCFType::type_id()`]: ../base/trait.TCFType.html#method.type_of +pub struct CFPropertyList(CFPropertyListRef); + +impl Drop for CFPropertyList { + fn drop(&mut self) { + unsafe { CFRelease(self.as_CFTypeRef()) } + } +} + +impl CFPropertyList { + #[inline] + pub fn as_concrete_TypeRef(&self) -> CFPropertyListRef { + self.0 + } + + #[inline] + pub unsafe fn wrap_under_get_rule(reference: CFPropertyListRef) -> CFPropertyList { + let reference = mem::transmute(CFRetain(mem::transmute(reference))); + CFPropertyList(reference) + } + + #[inline] + pub fn as_CFType(&self) -> CFType { + unsafe { CFType::wrap_under_get_rule(self.as_CFTypeRef()) } + } + + #[inline] + pub fn as_CFTypeRef(&self) -> ::core_foundation_sys::base::CFTypeRef { + unsafe { mem::transmute(self.as_concrete_TypeRef()) } + } + + #[inline] + pub unsafe fn wrap_under_create_rule(obj: CFPropertyListRef) -> CFPropertyList { + CFPropertyList(obj) + } + + /// Returns the reference count of the object. It is unwise to do anything other than test + /// whether the return value of this method is greater than zero. + #[inline] + pub fn retain_count(&self) -> CFIndex { + unsafe { CFGetRetainCount(self.as_CFTypeRef()) } + } + + /// Returns the type ID of this object. Will be one of CFData, CFString, CFArray, CFDictionary, + /// CFDate, CFBoolean, or CFNumber. + #[inline] + pub fn type_of(&self) -> CFTypeID { + unsafe { CFGetTypeID(self.as_CFTypeRef()) } + } + + /// Writes a debugging version of this object on standard error. + pub fn show(&self) { + unsafe { CFShow(self.as_CFTypeRef()) } + } + + /// Returns true if this value is an instance of another type. + #[inline] + pub fn instance_of>( + &self, + ) -> bool { + self.type_of() == >::type_id() + } +} + +impl Clone for CFPropertyList { + #[inline] + fn clone(&self) -> CFPropertyList { + unsafe { CFPropertyList::wrap_under_get_rule(self.0) } + } +} + +impl PartialEq for CFPropertyList { + #[inline] + fn eq(&self, other: &CFPropertyList) -> bool { + self.as_CFType().eq(&other.as_CFType()) + } +} + +impl Eq for CFPropertyList {} + +impl CFPropertyList { + /// Try to downcast the [`CFPropertyList`] to a subclass. Checking if the instance is the correct + /// subclass happens at runtime and an error is returned if it is not the correct type. + /// Works similar to [`Box::downcast`]. + /// + /// # Examples + /// + /// ``` + /// # use core_foundation::string::CFString; + /// # use core_foundation::propertylist::{CFPropertyList, CFPropertyListSubClass}; + /// # + /// // Create a string. + /// let string: CFString = CFString::from_static_string("FooBar"); + /// // Cast it up to a property list. + /// let propertylist: CFPropertyList = string.to_CFPropertyList(); + /// // Cast it down again. + /// assert!(propertylist.downcast::<_, CFString>().unwrap().to_string() == "FooBar"); + /// ``` + /// + /// [`CFPropertyList`]: struct.CFPropertyList.html + /// [`Box::downcast`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast + pub fn downcast>(&self) -> Option { + if self.instance_of::<_, T>() { + Some(unsafe { T::wrap_under_get_rule(self.0 as *const Raw) }) + } else { + None + } + } +} + + + #[cfg(test)] pub mod test { + use super::*; + use string::CFString; + use boolean::CFBoolean; + #[test] fn test_property_list_serialization() { use base::{TCFType, CFEqual}; use boolean::CFBoolean; - use number::number; + use number::CFNumber; use dictionary::CFDictionary; use string::CFString; use super::*; @@ -72,7 +226,7 @@ pub mod test { let boo = CFString::from_static_string("Boo"); let foo = CFString::from_static_string("Foo"); let tru = CFBoolean::true_value(); - let n42 = number(42); + let n42 = CFNumber::from(42); let dict1 = CFDictionary::from_CFType_pairs(&[(bar.as_CFType(), boo.as_CFType()), (baz.as_CFType(), tru.as_CFType()), @@ -84,4 +238,18 @@ pub mod test { assert!(CFEqual(dict1.as_CFTypeRef(), dict2) == 1); } } + + #[test] + fn downcast_string() { + let propertylist = CFString::from_static_string("Bar").to_CFPropertyList(); + assert!(propertylist.downcast::<_, CFString>().unwrap().to_string() == "Bar"); + assert!(propertylist.downcast::<_, CFBoolean>().is_none()); + } + + #[test] + fn downcast_boolean() { + let propertylist = CFBoolean::true_value().to_CFPropertyList(); + assert!(propertylist.downcast::<_, CFBoolean>().is_some()); + assert!(propertylist.downcast::<_, CFString>().is_none()); + } } diff --git a/third_party/rust/core-foundation/src/runloop.rs b/third_party/rust/core-foundation/src/runloop.rs index ccc1f78edbc9..fa2de8021d46 100644 --- a/third_party/rust/core-foundation/src/runloop.rs +++ b/third_party/rust/core-foundation/src/runloop.rs @@ -13,11 +13,13 @@ pub use core_foundation_sys::runloop::*; use core_foundation_sys::base::{CFIndex, CFRelease}; use core_foundation_sys::base::{kCFAllocatorDefault, CFOptionFlags}; use core_foundation_sys::string::CFStringRef; -use core_foundation_sys::date::{CFAbsoluteTime, CFTimeInterval}; use base::{TCFType}; +use date::{CFAbsoluteTime, CFTimeInterval}; use string::{CFString}; +pub type CFRunLoopMode = CFStringRef; + pub struct CFRunLoop(CFRunLoopRef); impl Drop for CFRunLoop { @@ -29,6 +31,7 @@ impl Drop for CFRunLoop { } impl_TCFType!(CFRunLoop, CFRunLoopRef, CFRunLoopGetTypeID); +impl_CFTypeDescription!(CFRunLoop); impl CFRunLoop { pub fn get_current() -> CFRunLoop { @@ -69,18 +72,60 @@ impl CFRunLoop { } } - pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) -> bool { + pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) -> bool { unsafe { CFRunLoopContainsTimer(self.0, timer.0, mode) != 0 } } - pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) { + pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) { unsafe { CFRunLoopAddTimer(self.0, timer.0, mode); } } + pub fn remove_timer(&self, timer: &CFRunLoopTimer, mode: CFRunLoopMode) { + unsafe { + CFRunLoopRemoveTimer(self.0, timer.0, mode); + } + } + + pub fn contains_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) -> bool { + unsafe { + CFRunLoopContainsSource(self.0, source.0, mode) != 0 + } + } + + pub fn add_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) { + unsafe { + CFRunLoopAddSource(self.0, source.0, mode); + } + } + + pub fn remove_source(&self, source: &CFRunLoopSource, mode: CFRunLoopMode) { + unsafe { + CFRunLoopRemoveSource(self.0, source.0, mode); + } + } + + pub fn contains_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) -> bool { + unsafe { + CFRunLoopContainsObserver(self.0, observer.0, mode) != 0 + } + } + + pub fn add_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) { + unsafe { + CFRunLoopAddObserver(self.0, observer.0, mode); + } + } + + pub fn remove_observer(&self, observer: &CFRunLoopObserver, mode: CFRunLoopMode) { + unsafe { + CFRunLoopRemoveObserver(self.0, observer.0, mode); + } + } + } pub struct CFRunLoopTimer(CFRunLoopTimerRef); @@ -104,17 +149,43 @@ impl CFRunLoopTimer { } } + +pub struct CFRunLoopSource(CFRunLoopSourceRef); + +impl Drop for CFRunLoopSource { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFRunLoopSource, CFRunLoopSourceRef, CFRunLoopSourceGetTypeID); + + +pub struct CFRunLoopObserver(CFRunLoopObserverRef); + +impl Drop for CFRunLoopObserver { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFRunLoopObserver, CFRunLoopObserverRef, CFRunLoopObserverGetTypeID); + #[cfg(test)] mod test { use super::*; - use core_foundation_sys::date::{CFAbsoluteTime, CFAbsoluteTimeGetCurrent}; + use date::{CFDate, CFAbsoluteTime}; use std::mem; use libc::c_void; #[test] fn wait_200_milliseconds() { let run_loop = CFRunLoop::get_current(); - let mut now = unsafe { CFAbsoluteTimeGetCurrent() }; + let mut now = CFDate::now().abs_time(); let mut context = unsafe { CFRunLoopTimerContext { version: 0, info: mem::transmute(&mut now), @@ -131,10 +202,10 @@ mod test { CFRunLoop::run_current(); } - extern "C" fn timer_popped(_timer: CFRunLoopTimerRef, _info: *mut c_void) { - let previous_now_ptr: *const CFAbsoluteTime = unsafe { mem::transmute(_info) }; + extern "C" fn timer_popped(_timer: CFRunLoopTimerRef, info: *mut c_void) { + let previous_now_ptr: *const CFAbsoluteTime = unsafe { mem::transmute(info) }; let previous_now = unsafe { *previous_now_ptr }; - let now = unsafe { CFAbsoluteTimeGetCurrent() }; + let now = CFDate::now().abs_time(); assert!(now - previous_now > 0.19 && now - previous_now < 0.21); CFRunLoop::get_current().stop(); } diff --git a/third_party/rust/core-foundation/src/set.rs b/third_party/rust/core-foundation/src/set.rs index 8224a20907c5..4dab26f5540c 100644 --- a/third_party/rust/core-foundation/src/set.rs +++ b/third_party/rust/core-foundation/src/set.rs @@ -29,6 +29,7 @@ impl Drop for CFSet { } impl_TCFType!(CFSet, CFSetRef, CFSetGetTypeID); +impl_CFTypeDescription!(CFSet); impl CFSet { /// Creates a new set from a list of `CFType` instances. diff --git a/third_party/rust/core-foundation/src/string.rs b/third_party/rust/core-foundation/src/string.rs index 051ca9a4e3b2..5026b71aec09 100644 --- a/third_party/rust/core-foundation/src/string.rs +++ b/third_party/rust/core-foundation/src/string.rs @@ -23,15 +23,6 @@ use std::ffi::CStr; /// An immutable string in one of a variety of encodings. pub struct CFString(CFStringRef); -impl Clone for CFString { - #[inline] - fn clone(&self) -> CFString { - unsafe { - TCFType::wrap_under_get_rule(self.0) - } - } -} - impl Drop for CFString { fn drop(&mut self) { unsafe { @@ -52,6 +43,13 @@ impl FromStr for CFString { } } +impl<'a> From<&'a str> for CFString { + #[inline] + fn from(string: &'a str) -> CFString { + CFString::new(string) + } +} + impl fmt::Display for CFString { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { unsafe { @@ -113,8 +111,7 @@ impl CFString { string.as_ptr(), string.len().to_CFIndex(), kCFStringEncodingUTF8, - false as Boolean, - kCFAllocatorNull); + false as Boolean); CFString::wrap_under_create_rule(string_ref) } } diff --git a/third_party/rust/core-foundation/src/timezone.rs b/third_party/rust/core-foundation/src/timezone.rs new file mode 100644 index 000000000000..5e2650d04398 --- /dev/null +++ b/third_party/rust/core-foundation/src/timezone.rs @@ -0,0 +1,101 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Core Foundation time zone objects. + +pub use core_foundation_sys::timezone::*; +use core_foundation_sys::base::{CFRelease, kCFAllocatorDefault}; + +use base::TCFType; +use date::{CFDate, CFTimeInterval}; + +#[cfg(feature = "with-chrono")] +use chrono::{FixedOffset, NaiveDateTime}; + +/// A time zone. +pub struct CFTimeZone(CFTimeZoneRef); + +impl Drop for CFTimeZone { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFTimeZone, CFTimeZoneRef, CFTimeZoneGetTypeID); +impl_CFTypeDescription!(CFTimeZone); + +impl Default for CFTimeZone { + fn default() -> CFTimeZone { + unsafe { + let tz_ref = CFTimeZoneCopyDefault(); + TCFType::wrap_under_create_rule(tz_ref) + } + } +} + +impl CFTimeZone { + #[inline] + pub fn new(interval: CFTimeInterval) -> CFTimeZone { + unsafe { + let tz_ref = CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, interval); + TCFType::wrap_under_create_rule(tz_ref) + } + } + + #[inline] + pub fn system() -> CFTimeZone { + unsafe { + let tz_ref = CFTimeZoneCopySystem(); + TCFType::wrap_under_create_rule(tz_ref) + } + } + + pub fn seconds_from_gmt(&self, date: CFDate) -> CFTimeInterval { + unsafe { + CFTimeZoneGetSecondsFromGMT(self.0, date.abs_time()) + } + } + + #[cfg(feature = "with-chrono")] + pub fn offset_at_date(&self, date: NaiveDateTime) -> FixedOffset { + let date = CFDate::from_naive_utc(date); + FixedOffset::east(self.seconds_from_gmt(date) as i32) + } + + #[cfg(feature = "with-chrono")] + pub fn from_offset(offset: FixedOffset) -> CFTimeZone { + CFTimeZone::new(offset.local_minus_utc() as f64) + } +} + +#[cfg(test)] +mod test { + use super::CFTimeZone; + + #[cfg(feature = "with-chrono")] + use chrono::{NaiveDateTime, FixedOffset}; + + #[test] + fn timezone_comparison() { + let system = CFTimeZone::system(); + let default = CFTimeZone::default(); + assert_eq!(system, default); + } + + #[test] + #[cfg(feature = "with-chrono")] + fn timezone_chrono_conversion() { + let offset = FixedOffset::west(28800); + let tz = CFTimeZone::from_offset(offset); + let converted = tz.offset_at_date(NaiveDateTime::from_timestamp(0, 0)); + assert_eq!(offset, converted); + } +} diff --git a/third_party/rust/core-foundation/src/url.rs b/third_party/rust/core-foundation/src/url.rs index 34c53b754174..85e05f351113 100644 --- a/third_party/rust/core-foundation/src/url.rs +++ b/third_party/rust/core-foundation/src/url.rs @@ -14,10 +14,18 @@ pub use core_foundation_sys::url::*; use base::{TCFType, CFIndex}; use string::{CFString}; -use core_foundation_sys::base::{kCFAllocatorDefault, CFRelease}; +use core_foundation_sys::base::{kCFAllocatorDefault, CFRelease, Boolean}; use std::fmt; use std::ptr; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::mem; + +use libc::{strlen, PATH_MAX}; + +#[cfg(unix)] +use std::os::unix::ffi::OsStrExt; +#[cfg(unix)] +use std::ffi::OsStr; pub struct CFURL(CFURLRef); @@ -43,13 +51,23 @@ impl fmt::Debug for CFURL { impl CFURL { pub fn from_path>(path: P, isDirectory: bool) -> Option { - 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; } @@ -64,6 +82,21 @@ impl CFURL { } } + #[cfg(unix)] + pub fn to_path(&self) -> Option { + // implementing this on Windows is more complicated because of the different OsStr representation + unsafe { + let mut buf: [u8; PATH_MAX as usize] = mem::uninitialized(); + let result = CFURLGetFileSystemRepresentation(self.0, true as Boolean, buf.as_mut_ptr(), buf.len() as CFIndex); + if result == false as Boolean { + return None; + } + let len = strlen(buf.as_ptr() as *const i8); + let path = OsStr::from_bytes(&buf[0..len]); + Some(PathBuf::from(path)) + } + } + pub fn get_string(&self) -> CFString { unsafe { TCFType::wrap_under_get_rule(CFURLGetString(self.0)) @@ -91,6 +124,17 @@ 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 = Path::new(OsStr::from_bytes(b"/\xC0/blame")); + let cfurl = CFURL::from_path(path, false).unwrap(); + assert_eq!(cfurl.to_path().unwrap(), path); + let len = unsafe { CFURLGetBytes(cfurl.as_concrete_TypeRef(), ptr::null_mut(), 0) }; + assert_eq!(len, 17); +} + #[test] fn absolute_file_url() { use core_foundation_sys::url::CFURLCreateWithFileSystemPathRelativeToBase; diff --git a/third_party/rust/core-foundation/src/uuid.rs b/third_party/rust/core-foundation/src/uuid.rs new file mode 100644 index 000000000000..3396c1659918 --- /dev/null +++ b/third_party/rust/core-foundation/src/uuid.rs @@ -0,0 +1,118 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Core Foundation UUID objects. + +#[cfg(feature = "with-uuid")] +extern crate uuid; + +pub use core_foundation_sys::uuid::*; +use core_foundation_sys::base::{CFRelease, kCFAllocatorDefault}; + +use base::TCFType; + +#[cfg(feature = "with-uuid")] +use self::uuid::Uuid; + +/// A UUID. +pub struct CFUUID(CFUUIDRef); + +impl Drop for CFUUID { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFUUID, CFUUIDRef, CFUUIDGetTypeID); +impl_CFTypeDescription!(CFUUID); + +impl CFUUID { + #[inline] + pub fn new() -> CFUUID { + unsafe { + let uuid_ref = CFUUIDCreate(kCFAllocatorDefault); + TCFType::wrap_under_create_rule(uuid_ref) + } + } +} + +#[cfg(feature = "with-uuid")] +impl Into for CFUUID { + fn into(self) -> Uuid { + let b = unsafe { + CFUUIDGetUUIDBytes(self.0) + }; + let bytes = [ + b.byte0, + b.byte1, + b.byte2, + b.byte3, + b.byte4, + b.byte5, + b.byte6, + b.byte7, + b.byte8, + b.byte9, + b.byte10, + b.byte11, + b.byte12, + b.byte13, + b.byte14, + b.byte15, + ]; + Uuid::from_bytes(&bytes).unwrap() + } +} + +#[cfg(feature = "with-uuid")] +impl From for CFUUID { + fn from(uuid: Uuid) -> CFUUID { + let b = uuid.as_bytes(); + let bytes = CFUUIDBytes { + byte0: b[0], + byte1: b[1], + byte2: b[2], + byte3: b[3], + byte4: b[4], + byte5: b[5], + byte6: b[6], + byte7: b[7], + byte8: b[8], + byte9: b[9], + byte10: b[10], + byte11: b[11], + byte12: b[12], + byte13: b[13], + byte14: b[14], + byte15: b[15], + }; + unsafe { + let uuid_ref = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, bytes); + TCFType::wrap_under_create_rule(uuid_ref) + } + } +} + + +#[cfg(test)] +#[cfg(feature = "with-uuid")] +mod test { + use super::CFUUID; + use uuid::Uuid; + + #[test] + fn uuid_conversion() { + let cf_uuid = CFUUID::new(); + let uuid: Uuid = cf_uuid.clone().into(); + let converted = CFUUID::from(uuid); + assert!(cf_uuid == converted); + } +} diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index 5496704b6dfb..829aac636c98 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -228,10 +228,10 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -257,7 +257,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -267,7 +267,7 @@ name = "core-text" version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1502,7 +1502,7 @@ dependencies = [ "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1529,7 +1529,7 @@ dependencies = [ "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1542,7 +1542,7 @@ name = "webrender_bindings" version = "0.1.0" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1613,9 +1613,9 @@ dependencies = [ "checksum clang-sys 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00048189ee171715296dfe3b2fcfd439563c7bfec0d98d3976ce3402d62c8f07" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" -"checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7" +"checksum core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e" "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" -"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" +"checksum core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5" "checksum core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc0a78ab2ac23b6ea7b3fe5fe93b227900dc0956979735b8f68032417976dd4" "checksum core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcad23756dd1dc4b47bf6a914ace27aadb8fa68889db5837af2308d018d0467c" "checksum cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec10816629f38fa557f08e199a3474fab954f4c8d2645550367235afa6e5646b" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index 5f5b1ab617e1..c3ef88347cde 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -228,10 +228,10 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -257,7 +257,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -267,7 +267,7 @@ name = "core-text" version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1514,7 +1514,7 @@ dependencies = [ "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1541,7 +1541,7 @@ dependencies = [ "bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1554,7 +1554,7 @@ name = "webrender_bindings" version = "0.1.0" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1625,9 +1625,9 @@ dependencies = [ "checksum clang-sys 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00048189ee171715296dfe3b2fcfd439563c7bfec0d98d3976ce3402d62c8f07" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" -"checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7" +"checksum core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e" "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624" -"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" +"checksum core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5" "checksum core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc0a78ab2ac23b6ea7b3fe5fe93b227900dc0956979735b8f68032417976dd4" "checksum core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcad23756dd1dc4b47bf6a914ace27aadb8fa68889db5837af2308d018d0467c" "checksum cose 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec10816629f38fa557f08e199a3474fab954f4c8d2645550367235afa6e5646b"