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..9b175fe --- /dev/null +++ b/core-foundation/src/propertylist.rs @@ -0,0 +1,87 @@ +// 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 libc::c_void; + +use error::CFError; +use data::CFData; +use base::{TCFType}; + +pub use core_foundation_sys::propertylist::*; +use core_foundation_sys::error::CFErrorRef; +use core_foundation_sys::base::{kCFAllocatorDefault}; + +pub fn create_with_data(data: CFData, + options: CFPropertyListMutabilityOptions) + -> Result<(*const c_void, 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, + &mut error); + if property_list.is_null() { + Err(TCFType::wrap_under_create_rule(error)) + } else { + Ok((property_list, format)) + } + } +} + +pub fn create_data(property_list: *const c_void, format: CFPropertyListFormat) -> Result { + unsafe { + let mut error: CFErrorRef = ptr::null_mut(); + let data_ref = CFPropertyListCreateData(kCFAllocatorDefault, + property_list, + format, + 0, + &mut error); + 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_CFTypeRef(), kCFPropertyListXMLFormat_v1_0).unwrap(); + let (dict2, _) = create_with_data(data, kCFPropertyListImmutable).unwrap(); + unsafe { + assert!(CFEqual(dict1.as_CFTypeRef(), dict2) == 1); + } + } +}