Implement AbstractCFType::type_id(). Switch to use CFTypeRef::downcast().
This commit is contained in:
@@ -3,6 +3,7 @@ use base::{
|
||||
CFAllocatorRef,
|
||||
CFIndex,
|
||||
CFRange,
|
||||
CFTypeID,
|
||||
CFTypeRef,
|
||||
CFWrapper,
|
||||
kCFAllocatorDefault,
|
||||
@@ -27,6 +28,7 @@ pub type CFArrayRef = *__CFArray;
|
||||
|
||||
pub impl CFArrayRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFArrayGetTypeID() }
|
||||
}
|
||||
|
||||
pub type CFArray<ElemRefType: AbstractCFTypeRef> = CFWrapper<CFArrayRef, ElemRefType, ()>;
|
||||
@@ -95,9 +97,17 @@ extern {
|
||||
|
||||
fn CFArrayCreate(allocator: CFAllocatorRef, values: **c_void,
|
||||
numValues: CFIndex, callBacks: *CFArrayCallBacks) -> CFArrayRef;
|
||||
|
||||
fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
|
||||
// CFArrayCreateCopy
|
||||
// CFArrayBSearchValues
|
||||
// CFArrayContainsValue
|
||||
fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex;
|
||||
// CFArrayGetCountOfValue
|
||||
// CFArrayGetFirstIndexOfValue
|
||||
// CFArrayGetLastIndexOfValue
|
||||
// CFArrayGetValues
|
||||
fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *c_void;
|
||||
// CFArrayApplyFunction
|
||||
fn CFArrayGetTypeID() -> CFTypeID;
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -5,6 +5,7 @@ use libc::c_long;
|
||||
// borrow semantics.
|
||||
trait AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef;
|
||||
static pure fn type_id() -> CFTypeID;
|
||||
}
|
||||
|
||||
pub type Boolean = u8;
|
||||
@@ -35,6 +36,13 @@ pub type CFTypeRef = *__CFType;
|
||||
|
||||
pub impl CFTypeRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self }
|
||||
// this can't be used, because CFType is the supertype and has no type id.
|
||||
static pure fn type_id() -> CFTypeID { fail; }
|
||||
}
|
||||
|
||||
pub pure fn downcast<T:AbstractCFTypeRef>(r: CFTypeRef) -> T unsafe {
|
||||
assert CFGetTypeID(r) == type_id::<T>();
|
||||
cast::transmute(r)
|
||||
}
|
||||
|
||||
struct CFWrapper<T:Copy AbstractCFTypeRef, PlaceholderType1, PlaceholderType2> {
|
||||
@@ -89,6 +97,7 @@ pub impl<T:Copy AbstractCFTypeRef, E1, E2>
|
||||
}
|
||||
|
||||
static fn from_CFType(wrapper: CFType) -> CFWrapper<T,E1,E2> unsafe {
|
||||
assert wrapper.type_id() == type_id::<T>();
|
||||
cast::transmute(move wrapper)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
use base::{
|
||||
AbstractCFTypeRef,
|
||||
CFTypeRef,
|
||||
CFTypeID,
|
||||
CFWrapper,
|
||||
};
|
||||
|
||||
pub type Boolean = u32;
|
||||
|
||||
struct __CFBoolean { private: () }
|
||||
pub type CFBooleanRef = *__CFBoolean;
|
||||
|
||||
pub impl CFBooleanRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFBooleanGetTypeID() }
|
||||
}
|
||||
|
||||
pub type CFBoolean = CFWrapper<CFBooleanRef, (), ()>;
|
||||
@@ -28,5 +32,8 @@ pub impl CFBoolean {
|
||||
extern {
|
||||
const kCFBooleanTrue: CFBooleanRef;
|
||||
const kCFBooleanFalse: CFBooleanRef;
|
||||
|
||||
fn CFBooleanGetValue(boolean: CFBooleanRef) -> Boolean;
|
||||
fn CFBooleanGetTypeID() -> CFTypeID;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ use base::{
|
||||
CFAllocatorRef,
|
||||
CFIndex,
|
||||
CFRange,
|
||||
CFType,
|
||||
CFTypeRef,
|
||||
CFTypeID,
|
||||
CFWrapper,
|
||||
kCFAllocatorDefault,
|
||||
};
|
||||
@@ -16,6 +16,7 @@ pub type CFDataRef = *__CFData;
|
||||
|
||||
impl CFDataRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFDataGetTypeID() }
|
||||
}
|
||||
|
||||
type CFData = CFWrapper<CFDataRef, (), ()>;
|
||||
@@ -66,4 +67,6 @@ extern {
|
||||
fn CFDataGetBytePtr(theData: CFDataRef) -> *u8;
|
||||
fn CFDataGetBytes(theData: CFDataRef, range: CFRange, buffer: *u8);
|
||||
fn CFDataGetLength(theData: CFDataRef) -> CFIndex;
|
||||
|
||||
fn CFDataGetTypeID() -> CFTypeID;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ pub type CFDictionaryRef = *__CFDictionary;
|
||||
|
||||
impl CFDictionaryRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFDictionaryGetTypeID() }
|
||||
}
|
||||
|
||||
pub type CFDictionary<KeyRefType, ValueRefType> = CFWrapper<CFDictionaryRef, KeyRefType, ValueRefType>;
|
||||
|
||||
@@ -36,6 +36,7 @@ pub type CFNumberRef = *__CFNumber;
|
||||
|
||||
pub impl CFNumberRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFNumberGetTypeID() }
|
||||
}
|
||||
|
||||
pub impl CFNumberRef {
|
||||
@@ -159,3 +160,13 @@ extern {
|
||||
//fn CFNumberCompare
|
||||
fn CFNumberGetTypeID() -> CFTypeID;
|
||||
}
|
||||
|
||||
fn should_fail_on_bad_downcast() {
|
||||
#[test];
|
||||
#[should_fail];
|
||||
|
||||
use boolean::CFBooleanRef;
|
||||
|
||||
let one = CFWrapper::to_CFType(CFNumber::new(1_i32));
|
||||
let casted = base::downcast::<CFBooleanRef>(*one.borrow_ref());
|
||||
}
|
||||
@@ -30,6 +30,7 @@ pub type CFSetRef = *__CFSet;
|
||||
|
||||
impl CFSetRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFSetGetTypeID() }
|
||||
}
|
||||
|
||||
pub type CFSet<ElemRefType: AbstractCFTypeRef> = CFWrapper<CFSetRef, ElemRefType, ()>;
|
||||
|
||||
@@ -199,6 +199,7 @@ pub type CFStringRef = *__CFString;
|
||||
|
||||
pub impl CFStringRef : AbstractCFTypeRef {
|
||||
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
|
||||
static pure fn type_id() -> CFTypeID unsafe { CFStringGetTypeID() }
|
||||
}
|
||||
|
||||
pub type CFString = CFWrapper<CFStringRef, (), ()>;
|
||||
|
||||
Reference in New Issue
Block a user