From 2560337ed877fffd06ea6af86570ac0a72b541d0 Mon Sep 17 00:00:00 2001 From: Christian Howe Date: Sun, 1 Jan 2017 19:38:22 -0500 Subject: [PATCH 1/3] Add CFPropertyList serialization --- core-foundation-sys/src/base.rs | 1 + core-foundation-sys/src/lib.rs | 1 + core-foundation-sys/src/propertylist.rs | 37 +++++++++++ core-foundation/src/lib.rs | 1 + core-foundation/src/propertylist.rs | 86 +++++++++++++++++++++++++ 5 files changed, 126 insertions(+) create mode 100644 core-foundation-sys/src/propertylist.rs create mode 100644 core-foundation/src/propertylist.rs diff --git a/core-foundation-sys/src/base.rs b/core-foundation-sys/src/base.rs index 6cf8cb6..5f29cd5 100644 --- a/core-foundation-sys/src/base.rs +++ b/core-foundation-sys/src/base.rs @@ -61,6 +61,7 @@ extern { //fn CFCopyTypeIDDescription //fn CFEqual //fn CFGetAllocator + pub fn CFEqual(cf1: CFTypeRef, cf2: CFTypeRef) -> Boolean; pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex; pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID; pub fn CFHash(cf: CFTypeRef) -> CFHashCode; diff --git a/core-foundation-sys/src/lib.rs b/core-foundation-sys/src/lib.rs index 2574689..b39da97 100644 --- a/core-foundation-sys/src/lib.rs +++ b/core-foundation-sys/src/lib.rs @@ -19,6 +19,7 @@ pub mod dictionary; pub mod error; pub mod messageport; pub mod number; +pub mod propertylist; pub mod runloop; pub mod set; pub mod string; diff --git a/core-foundation-sys/src/propertylist.rs b/core-foundation-sys/src/propertylist.rs new file mode 100644 index 0000000..2396ef9 --- /dev/null +++ b/core-foundation-sys/src/propertylist.rs @@ -0,0 +1,37 @@ +use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFTypeRef}; +use data::CFDataRef; +use error::CFErrorRef; + +pub type CFPropertyListRef = CFTypeRef; + +pub type CFPropertyListFormat = CFIndex; +pub const kCFPropertyListOpenStepFormat: CFPropertyListFormat = 1; +pub const kCFPropertyListXMLFormat_v1_0: CFPropertyListFormat = 100; +pub const kCFPropertyListBinaryFormat_v1_0: CFPropertyListFormat = 200; + +pub type CFPropertyListMutabilityOptions = CFOptionFlags; +pub const kCFPropertyListImmutable: CFPropertyListMutabilityOptions = 0; +pub const kCFPropertyListMutableContainers: CFPropertyListMutabilityOptions = 1; +pub const kCFPropertyListMutableContainersAndLeaves: CFPropertyListMutabilityOptions = 2; + +extern "C" { + // CFPropertyList.h + // + + // fn CFPropertyListCreateDeepCopy + // fn CFPropertyListIsValid + pub fn CFPropertyListCreateWithData(allocator: CFAllocatorRef, + data: CFDataRef, + options: CFPropertyListMutabilityOptions, + format: *mut CFPropertyListFormat, + error: *mut CFErrorRef) + -> CFPropertyListRef; + // fn CFPropertyListCreateWithStream + // fn CFPropertyListWrite + pub fn CFPropertyListCreateData(allocator: CFAllocatorRef, + propertyList: CFPropertyListRef, + format: CFPropertyListFormat, + options: CFOptionFlags, + error: *mut CFErrorRef) + -> CFDataRef; +} diff --git a/core-foundation/src/lib.rs b/core-foundation/src/lib.rs index 345b123..d8a305b 100644 --- a/core-foundation/src/lib.rs +++ b/core-foundation/src/lib.rs @@ -60,6 +60,7 @@ pub mod set; pub mod string; pub mod url; pub mod bundle; +pub mod propertylist; pub mod runloop; #[cfg(test)] diff --git a/core-foundation/src/propertylist.rs b/core-foundation/src/propertylist.rs new file mode 100644 index 0000000..01d43e1 --- /dev/null +++ b/core-foundation/src/propertylist.rs @@ -0,0 +1,86 @@ +// 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 property lists + +use std::ptr; + +use error::CFError; +use data::CFData; +use base::{CFType, TCFType}; + +pub use core_foundation_sys::propertylist::*; +use core_foundation_sys::error::CFErrorRef; +use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; + +pub fn create_with_data(data: CFData, + options: CFPropertyListMutabilityOptions) + -> Result<(CFType, CFPropertyListFormat), CFError> { + unsafe { + let mut error: CFErrorRef = ptr::null_mut(); + let mut format: CFPropertyListFormat = 0; + let property_list = CFPropertyListCreateWithData(kCFAllocatorDefault, + data.as_concrete_TypeRef(), + options, + &mut format as *mut CFPropertyListFormat, + &mut error as *mut CFErrorRef); + if property_list.is_null() { + Err(TCFType::wrap_under_create_rule(error)) + } else { + Ok((TCFType::wrap_under_create_rule(property_list), format)) + } + } +} + +pub fn create_data(property_list: CFType, format: CFPropertyListFormat) -> Result { + unsafe { + let mut error: CFErrorRef = ptr::null_mut(); + let property_list_ref: CFTypeRef = property_list.as_CFTypeRef(); + let data_ref = CFPropertyListCreateData(kCFAllocatorDefault, + property_list_ref, + format, + 0, + &mut error as *mut CFErrorRef); + if data_ref.is_null() { + Err(TCFType::wrap_under_create_rule(error)) + } else { + Ok(TCFType::wrap_under_create_rule(data_ref)) + } + } +} + +#[cfg(test)] +pub mod test { + #[test] + fn test_property_list_serialization() { + use base::{TCFType, CFEqual}; + use boolean::CFBoolean; + use number::number; + use dictionary::CFDictionary; + use string::CFString; + use super::*; + + let bar = CFString::from_static_string("Bar"); + let baz = CFString::from_static_string("Baz"); + let boo = CFString::from_static_string("Boo"); + let foo = CFString::from_static_string("Foo"); + let tru = CFBoolean::true_value(); + let n42 = number(42); + + let dict1 = CFDictionary::from_CFType_pairs(&[(bar.as_CFType(), boo.as_CFType()), + (baz.as_CFType(), tru.as_CFType()), + (foo.as_CFType(), n42.as_CFType())]); + + let data = create_data(dict1.as_CFType(), kCFPropertyListXMLFormat_v1_0).unwrap(); + let (dict2, _) = create_with_data(data, kCFPropertyListImmutable).unwrap(); + unsafe { + assert!(CFEqual(dict1.as_CFTypeRef(), dict2.as_CFTypeRef()) == 1); + } + } +} From 506b1fd402e837ccfcc9fac460095d05f7027dbd Mon Sep 17 00:00:00 2001 From: Christian Howe Date: Wed, 4 Jan 2017 15:29:49 -0500 Subject: [PATCH 2/3] Use *const c_void in propertylist functions for consistency --- core-foundation/src/propertylist.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core-foundation/src/propertylist.rs b/core-foundation/src/propertylist.rs index 01d43e1..a14a42b 100644 --- a/core-foundation/src/propertylist.rs +++ b/core-foundation/src/propertylist.rs @@ -11,17 +11,19 @@ use std::ptr; +use libc::c_void; + use error::CFError; use data::CFData; -use base::{CFType, TCFType}; +use base::{TCFType}; pub use core_foundation_sys::propertylist::*; use core_foundation_sys::error::CFErrorRef; -use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; +use core_foundation_sys::base::{kCFAllocatorDefault}; pub fn create_with_data(data: CFData, options: CFPropertyListMutabilityOptions) - -> Result<(CFType, CFPropertyListFormat), CFError> { + -> Result<(*const c_void, CFPropertyListFormat), CFError> { unsafe { let mut error: CFErrorRef = ptr::null_mut(); let mut format: CFPropertyListFormat = 0; @@ -33,17 +35,16 @@ pub fn create_with_data(data: CFData, if property_list.is_null() { Err(TCFType::wrap_under_create_rule(error)) } else { - Ok((TCFType::wrap_under_create_rule(property_list), format)) + Ok((property_list, format)) } } } -pub fn create_data(property_list: CFType, format: CFPropertyListFormat) -> Result { +pub fn create_data(property_list: *const c_void, format: CFPropertyListFormat) -> Result { unsafe { let mut error: CFErrorRef = ptr::null_mut(); - let property_list_ref: CFTypeRef = property_list.as_CFTypeRef(); let data_ref = CFPropertyListCreateData(kCFAllocatorDefault, - property_list_ref, + property_list, format, 0, &mut error as *mut CFErrorRef); @@ -77,10 +78,10 @@ pub mod test { (baz.as_CFType(), tru.as_CFType()), (foo.as_CFType(), n42.as_CFType())]); - let data = create_data(dict1.as_CFType(), kCFPropertyListXMLFormat_v1_0).unwrap(); + let data = create_data(dict1.as_CFTypeRef(), kCFPropertyListXMLFormat_v1_0).unwrap(); let (dict2, _) = create_with_data(data, kCFPropertyListImmutable).unwrap(); unsafe { - assert!(CFEqual(dict1.as_CFTypeRef(), dict2.as_CFTypeRef()) == 1); + assert!(CFEqual(dict1.as_CFTypeRef(), dict2) == 1); } } } From 37e11bd27e59b72aac2cd1ff56eff86fcbeecbf8 Mon Sep 17 00:00:00 2001 From: Christian Howe Date: Wed, 4 Jan 2017 19:44:37 -0500 Subject: [PATCH 3/3] Remove unnecessary casts in propertylist --- core-foundation/src/propertylist.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-foundation/src/propertylist.rs b/core-foundation/src/propertylist.rs index a14a42b..9b175fe 100644 --- a/core-foundation/src/propertylist.rs +++ b/core-foundation/src/propertylist.rs @@ -30,8 +30,8 @@ pub fn create_with_data(data: CFData, let property_list = CFPropertyListCreateWithData(kCFAllocatorDefault, data.as_concrete_TypeRef(), options, - &mut format as *mut CFPropertyListFormat, - &mut error as *mut CFErrorRef); + &mut format, + &mut error); if property_list.is_null() { Err(TCFType::wrap_under_create_rule(error)) } else { @@ -47,7 +47,7 @@ pub fn create_data(property_list: *const c_void, format: CFPropertyListFormat) - property_list, format, 0, - &mut error as *mut CFErrorRef); + &mut error); if data_ref.is_null() { Err(TCFType::wrap_under_create_rule(error)) } else {