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 #90

Merged
merged 3 commits into from Jan 5, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Add CFPropertyList serialization

  • Loading branch information
Christian Howe
Christian Howe committed Jan 2, 2017
commit 2560337ed877fffd06ea6af86570ac0a72b541d0
@@ -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;
@@ -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;
}
@@ -60,6 +60,7 @@ pub mod set;
pub mod string;
pub mod url;
pub mod bundle;
pub mod propertylist;
pub mod runloop;

#[cfg(test)]
@@ -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> {

This comment has been minimized.

@ghost

ghost Jan 3, 2017

Author

I'm not sure that using CFType here is appropriate, especially without an easy way to downcast it to a concrete type. Other parts of the API use *const c_void for these generic types instead.

This comment has been minimized.

@ghost

ghost Jan 4, 2017

Author

I've now converted this to use *const c_void, keeping it consistent with other parts of the API.

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);

This comment has been minimized.

@jdm

jdm Jan 4, 2017

Member

These casts shouldn't be necessary.

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);

This comment has been minimized.

@jdm

jdm Jan 4, 2017

Member

This cast shouldn't be necessary.

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.