From dfec7c491f9c6601e1495ea5288b44344e8c4605 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 30 Aug 2012 19:14:36 -0700 Subject: [PATCH] Add CFNumbers --- base.rs | 13 +++++++--- core_foundation.rc | 1 + number.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++ test.rs | 9 +++++-- 4 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 number.rs diff --git a/base.rs b/base.rs index 55c09bc..d1801c7 100644 --- a/base.rs +++ b/base.rs @@ -31,16 +31,22 @@ trait AbstractCFType { } trait CFTypeOps { - fn as_type(self) -> CFType; + fn as_type(&self) -> CFType; + fn retain_count(&self) -> CFIndex; fn show(&self); } impl T : CFTypeOps { - // Consumes self. - fn as_type(self) -> CFType { + // FIXME: Should move, but there's a linearity bug. + fn as_type(&self) -> CFType { + CFRetain(self.as_type_ref()); CFType { obj: self.as_type_ref() } } + fn retain_count(&self) -> CFIndex { + CFGetRetainCount(self.as_type_ref()) + } + fn show(&self) { CFShow(self.as_type_ref()); } @@ -60,6 +66,7 @@ extern { const kCFAllocatorNull: CFAllocatorRef; const kCFAllocatorUseContext: CFAllocatorRef; + fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex; fn CFRetain(cf: CFTypeRef) -> CFTypeRef; fn CFRelease(cf: CFTypeRef); diff --git a/core_foundation.rc b/core_foundation.rc index 7b0ee0c..b853222 100644 --- a/core_foundation.rc +++ b/core_foundation.rc @@ -1,6 +1,7 @@ mod base; mod boolean; mod dictionary; +mod number; mod string; mod test; diff --git a/number.rs b/number.rs new file mode 100644 index 0000000..d8ed31f --- /dev/null +++ b/number.rs @@ -0,0 +1,59 @@ +use base::{AbstractCFType, CFAllocatorRef, CFIndex, CFRelease, CFTypeRef, kCFAllocatorDefault}; +use libc::{c_int, c_void}; +use unsafe::reinterpret_cast; + +struct __CFNumber { private: () } +pub type CFNumberRef = *__CFNumber; + +const kCFNumberSInt32Type: c_int = 3; + +struct CFNumber { + obj: CFNumberRef, + + drop { + unsafe { + CFRelease(reinterpret_cast(self.obj)); + } + } +} + +mod CFNumber { + fn wrap(obj: CFNumberRef) -> CFNumber { + CFNumber { obj: obj } + } + + fn new_number(n: T) -> CFNumber { + unsafe { + CFNumber { + obj: CFNumberCreate(kCFAllocatorDefault, n.cf_number_type(), reinterpret_cast(&n)) + } + } + } +} + +impl CFNumber : AbstractCFType { + pure fn as_type_ref(&self) -> CFTypeRef { + unsafe { + reinterpret_cast(self.obj) + } + } +} + +trait ConvertibleToCFNumber { + // FIXME: Should be static, but that breaks. + pure fn cf_number_type(self) -> CFNumberType; +} + +impl i32 : ConvertibleToCFNumber { + pure fn cf_number_type(self) -> CFNumberType { kCFNumberSInt32Type as CFNumberType } +} + +type CFNumberType = CFIndex; + +#[link_args="-framework CoreFoundation"] +#[nolink] +extern { + fn CFNumberCreate(allocator: CFAllocatorRef, theType: CFNumberType, valuePtr: *c_void) + -> CFNumberRef; +} + diff --git a/test.rs b/test.rs index edd2a5e..29856bf 100644 --- a/test.rs +++ b/test.rs @@ -1,12 +1,17 @@ use base::CFTypeOps; use boolean::CFBoolean; +use number::CFNumber; use dictionary::CFDictionary; use string::CFString; fn main() { + /*let n = CFNumber::new_number(42 as i32); + io::println(fmt!("%d", (&n).retain_count() as int)); + (&n).show();*/ let d = CFDictionary::new_dictionary([ - (CFString::new_static("Foo"), CFString::new_static("Bar").as_type()), - (CFString::new_static("Baz"), CFBoolean::true_value().as_type()) + (CFString::new_static("Foo"), (&CFString::new_static("Bar")).as_type()), + (CFString::new_static("Baz"), (&CFBoolean::true_value()).as_type()), + (CFString::new_static("Boo"), (&CFNumber::new_number(42 as i32)).as_type()), ]); (&d).show(); }