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
+127
−0
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
Loading status checks…
Add CFPropertyList serialization
- Loading branch information
| @@ -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; | ||
| } |
| @@ -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> { | ||
ghost
Author
|
||
| 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
I'm not sure that using
CFTypehere is appropriate, especially without an easy way to downcast it to a concrete type. Other parts of the API use*const c_voidfor these generic types instead.