diff --git a/core-foundation-sys/src/uuid.rs b/core-foundation-sys/src/uuid.rs index 21e8c89..63c180f 100644 --- a/core-foundation-sys/src/uuid.rs +++ b/core-foundation-sys/src/uuid.rs @@ -8,7 +8,7 @@ // except according to those terms. use libc::c_void; -use base::CFAllocatorRef; +use base::{CFAllocatorRef, CFTypeID}; #[repr(C)] pub struct __CFUUID(c_void); @@ -16,28 +16,33 @@ pub struct __CFUUID(c_void); pub type CFUUIDRef = *const __CFUUID; #[repr(C)] +#[derive(Clone, Copy, Default)] pub struct CFUUIDBytes { - byte0: u8, - byte1: u8, - byte2: u8, - byte3: u8, - byte4: u8, - byte5: u8, - byte6: u8, - byte7: u8, - byte8: u8, - byte9: u8, - byte10: u8, - byte11: u8, - byte12: u8, - byte13: u8, - byte14: u8, - byte15: u8 + 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/core-foundation/Cargo.toml b/core-foundation/Cargo.toml index a5bb239..02127c0 100644 --- a/core-foundation/Cargo.toml +++ b/core-foundation/Cargo.toml @@ -13,7 +13,9 @@ version = "0.4.4" [dependencies] libc = "0.2" +uuid = { version = "0.5", optional = true } [features] mac_os_10_7_support = ["core-foundation-sys/mac_os_10_7_support"] # backwards compatibility mac_os_10_8_features = ["core-foundation-sys/mac_os_10_8_features"] # enables new features +with-uuid = ["uuid"] diff --git a/core-foundation/src/lib.rs b/core-foundation/src/lib.rs index f4ca71d..b565055 100644 --- a/core-foundation/src/lib.rs +++ b/core-foundation/src/lib.rs @@ -62,6 +62,7 @@ pub mod url; pub mod bundle; pub mod propertylist; pub mod runloop; +pub mod uuid; #[cfg(test)] pub mod test { diff --git a/core-foundation/src/uuid.rs b/core-foundation/src/uuid.rs new file mode 100644 index 0000000..f196567 --- /dev/null +++ b/core-foundation/src/uuid.rs @@ -0,0 +1,117 @@ +// 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 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); + } +}