Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CFPropertyList serialization #88

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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;
@@ -72,4 +72,8 @@ extern {
pub fn CFDictionarySetValue(theDict: CFMutableDictionaryRef,
key: *const c_void,
value: *const c_void);
pub fn CFDictionaryGetKeysAndValues(theDict: CFDictionaryRef,
keys: *mut *const c_void,
values: *mut *const c_void);

}
@@ -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;
@@ -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;
}
@@ -101,4 +101,18 @@ impl CFDictionary {
pub unsafe fn set_value(&self, key: *const c_void, value: *const c_void) {
CFDictionarySetValue(self.0, key, value)
}

pub fn get_keys_and_values(&self) -> (Vec<*const c_void>, Vec<*const c_void>) {
let length = self.len();
let mut keys = Vec::with_capacity(length);
let mut values = Vec::with_capacity(length);

unsafe {
CFDictionaryGetKeysAndValues(self.0, keys.as_mut_ptr(), values.as_mut_ptr());
keys.set_len(length);
values.set_len(length);
}

(keys, values)
}
}
@@ -60,6 +60,7 @@ pub mod set;
pub mod string;
pub mod url;
pub mod bundle;
pub mod propertylist;
pub mod runloop;

#[cfg(test)]
@@ -83,10 +84,15 @@ pub mod test {
let tru = CFBoolean::true_value();
let n42 = number(42);

let _d = CFDictionary::from_CFType_pairs(&[
let d = CFDictionary::from_CFType_pairs(&[
(bar.as_CFType(), boo.as_CFType()),
(baz.as_CFType(), tru.as_CFType()),
(foo.as_CFType(), n42.as_CFType()),
]);

let (v1, v2) = d.get_keys_and_values();

assert!(v1 == &[bar.as_CFTypeRef(), baz.as_CFTypeRef(), foo.as_CFTypeRef()]);
assert!(v2 == &[boo.as_CFTypeRef(), tru.as_CFTypeRef(), n42.as_CFTypeRef()]);
}
}
@@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<CFData, CFError> {
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);
}
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.