Implement AbstractCFType::type_id(). Switch to use CFTypeRef::downcast().

This commit is contained in:
Brian J. Burg
2012-11-16 14:29:57 -08:00
parent 6bac6b0601
commit 04c0856f7d
10 changed files with 47 additions and 4 deletions
+12 -2
View File
@@ -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]
+9
View File
@@ -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)
}
+7
View File
@@ -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;
}
+4 -1
View File
@@ -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;
}
+1
View File
@@ -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>;
+11
View File
@@ -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());
}
+1
View File
@@ -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, ()>;
+1
View File
@@ -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, (), ()>;
-1
View File
@@ -22,4 +22,3 @@ fn main() {
]);
d.show();
}
+1
View File
@@ -20,6 +20,7 @@ pub type CFURLRef = *__CFURL;
impl CFURLRef : AbstractCFTypeRef {
pure fn as_type_ref(&self) -> CFTypeRef { *self as CFTypeRef }
static pure fn type_id() -> CFTypeID unsafe { CFURLGetTypeID() }
}
pub type CFURL = CFWrapper<CFURLRef, (), ()>;