diff --git a/.gitignore b/.gitignore index 2a66ba7..be576c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/Cargo.lock -/target +Cargo.lock +target/ diff --git a/.travis.yml b/.travis.yml index d5979d3..bfb6c36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,8 @@ language: rust rust: nightly os: osx + +script: + - cd core-foundation + - cargo build --verbose + - cargo test --verbose diff --git a/core-foundation-sys/Cargo.toml b/core-foundation-sys/Cargo.toml new file mode 100644 index 0000000..523bd46 --- /dev/null +++ b/core-foundation-sys/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "core-foundation-sys" +description = "Bindings to Core Foundation for OS X" +homepage = "https://github.com/servo/core-foundation-rs" +repository = "https://github.com/servo/core-foundation-rs" +version = "0.1.0" +authors = ["The Servo Project Developers"] +license = "MIT / Apache-2.0" +build = "build.rs" +links = "CoreFoundation.framework" + +[dependencies] +libc = "0.1" diff --git a/core-foundation-sys/build.rs b/core-foundation-sys/build.rs new file mode 100644 index 0000000..a1a0ea1 --- /dev/null +++ b/core-foundation-sys/build.rs @@ -0,0 +1,12 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + println!("cargo:rustc-link-lib=framework=CoreFoundation"); +} diff --git a/core-foundation-sys/src/array.rs b/core-foundation-sys/src/array.rs new file mode 100644 index 0000000..910030d --- /dev/null +++ b/core-foundation-sys/src/array.rs @@ -0,0 +1,60 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use base::{CFIndex, CFAllocatorRef, CFTypeID}; + +/// FIXME(pcwalton): This is wrong. +pub type CFArrayRetainCallBack = *const u8; + +/// FIXME(pcwalton): This is wrong. +pub type CFArrayReleaseCallBack = *const u8; + +/// FIXME(pcwalton): This is wrong. +pub type CFArrayCopyDescriptionCallBack = *const u8; + +/// FIXME(pcwalton): This is wrong. +pub type CFArrayEqualCallBack = *const u8; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFArrayCallBacks { + pub version: CFIndex, + pub retain: CFArrayRetainCallBack, + pub release: CFArrayReleaseCallBack, + pub copyDescription: CFArrayCopyDescriptionCallBack, + pub equal: CFArrayEqualCallBack, +} + +#[repr(C)] +struct __CFArray(c_void); + +pub type CFArrayRef = *const __CFArray; + +extern { + /* + * CFArray.h + */ + pub static kCFTypeArrayCallBacks: CFArrayCallBacks; + + pub fn CFArrayCreate(allocator: CFAllocatorRef, values: *const *const c_void, + numValues: CFIndex, callBacks: *const CFArrayCallBacks) -> CFArrayRef; + // CFArrayCreateCopy + // CFArrayBSearchValues + // CFArrayContainsValue + pub fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex; + // CFArrayGetCountOfValue + // CFArrayGetFirstIndexOfValue + // CFArrayGetLastIndexOfValue + // CFArrayGetValues + pub fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *const c_void; + // CFArrayApplyFunction + pub fn CFArrayGetTypeID() -> CFTypeID; +} diff --git a/core-foundation-sys/src/base.rs b/core-foundation-sys/src/base.rs new file mode 100644 index 0000000..6cf8cb6 --- /dev/null +++ b/core-foundation-sys/src/base.rs @@ -0,0 +1,74 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::{c_uint, c_long, c_ulong, c_void}; + +pub type Boolean = u8; +pub type CFIndex = c_long; +pub type mach_port_t = c_uint; +pub type CFAllocatorRef = *const c_void; +pub type CFNullRef = *const c_void; +pub type CFHashCode = c_ulong; +pub type CFTypeID = c_ulong; +pub type CFTypeRef = *const c_void; +pub type CFOptionFlags = u32; +pub type OSStatus = i32; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFRange { + pub location: CFIndex, + pub length: CFIndex +} + +// for back-compat +impl CFRange { + pub fn init(location: CFIndex, length: CFIndex) -> CFRange { + CFRange { + location: location, + length: length, + } + } +} + +extern { + /* + * CFBase.h + */ + + /* CFAllocator Reference */ + // N.B. Many CFAllocator functions and constants are omitted here. + pub static kCFAllocatorDefault: CFAllocatorRef; + pub static kCFAllocatorSystemDefault: CFAllocatorRef; + pub static kCFAllocatorMalloc: CFAllocatorRef; + pub static kCFAllocatorMallocZone: CFAllocatorRef; + pub static kCFAllocatorNull: CFAllocatorRef; + pub static kCFAllocatorUseContext: CFAllocatorRef; + + /* CFNull Reference */ + + pub static kCFNull: CFNullRef; + + /* CFType Reference */ + + //fn CFCopyDescription + //fn CFCopyTypeIDDescription + //fn CFEqual + //fn CFGetAllocator + pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex; + pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID; + pub fn CFHash(cf: CFTypeRef) -> CFHashCode; + //fn CFMakeCollectable + pub fn CFRelease(cf: CFTypeRef); + pub fn CFRetain(cf: CFTypeRef) -> CFTypeRef; + pub fn CFShow(obj: CFTypeRef); + + /* Base Utilities Reference */ + // N.B. Some things missing here. +} diff --git a/core-foundation-sys/src/bundle.rs b/core-foundation-sys/src/bundle.rs new file mode 100644 index 0000000..0999a83 --- /dev/null +++ b/core-foundation-sys/src/bundle.rs @@ -0,0 +1,28 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use base::CFTypeID; +use string::CFStringRef; + +#[repr(C)] +struct __CFBundle(c_void); + +pub type CFBundleRef = *const __CFBundle; + +extern { + /* + * CFBundle.h + */ + pub fn CFBundleGetBundleWithIdentifier(bundleID: CFStringRef) -> CFBundleRef; + pub fn CFBundleGetFunctionPointerForName(bundle: CFBundleRef, function_name: CFStringRef) -> *const c_void; + + pub fn CFBundleGetTypeID() -> CFTypeID; +} diff --git a/core-foundation-sys/src/data.rs b/core-foundation-sys/src/data.rs new file mode 100644 index 0000000..0e333b5 --- /dev/null +++ b/core-foundation-sys/src/data.rs @@ -0,0 +1,22 @@ +use libc::c_void; + +use base::{CFAllocatorRef, CFTypeID, CFIndex}; + +#[repr(C)] +struct __CFData(c_void); + +pub type CFDataRef = *const __CFData; + +extern { + /* + * CFData.h + */ + + pub fn CFDataCreate(allocator: CFAllocatorRef, + bytes: *const u8, length: CFIndex) -> CFDataRef; + //fn CFDataFind + pub fn CFDataGetBytePtr(theData: CFDataRef) -> *const u8; + pub fn CFDataGetLength(theData: CFDataRef) -> CFIndex; + + pub fn CFDataGetTypeID() -> CFTypeID; +} diff --git a/src/date.rs b/core-foundation-sys/src/date.rs similarity index 88% rename from src/date.rs rename to core-foundation-sys/src/date.rs index df1c818..81b3f58 100644 --- a/src/date.rs +++ b/core-foundation-sys/src/date.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::{c_void}; + +use base::{CFAllocatorRef, CFIndex, CFTypeID, Boolean}; + +pub type CFDictionaryApplierFunction = *const u8; +pub type CFDictionaryCopyDescriptionCallBack = *const u8; +pub type CFDictionaryEqualCallBack = *const u8; +pub type CFDictionaryHashCallBack = *const u8; +pub type CFDictionaryReleaseCallBack = *const u8; +pub type CFDictionaryRetainCallBack = *const u8; + +#[allow(dead_code)] +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFDictionaryKeyCallBacks { + pub version: CFIndex, + pub retain: CFDictionaryRetainCallBack, + pub release: CFDictionaryReleaseCallBack, + pub copyDescription: CFDictionaryCopyDescriptionCallBack, + pub equal: CFDictionaryEqualCallBack, + pub hash: CFDictionaryHashCallBack +} + +#[allow(dead_code)] +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFDictionaryValueCallBacks { + pub version: CFIndex, + pub retain: CFDictionaryRetainCallBack, + pub release: CFDictionaryReleaseCallBack, + pub copyDescription: CFDictionaryCopyDescriptionCallBack, + pub equal: CFDictionaryEqualCallBack +} + +#[repr(C)] +struct __CFDictionary(c_void); + +pub type CFDictionaryRef = *const __CFDictionary; + +extern { + /* + * CFDictionary.h + */ + + pub static kCFTypeDictionaryKeyCallBacks: CFDictionaryKeyCallBacks; + pub static kCFTypeDictionaryValueCallBacks: CFDictionaryValueCallBacks; + + pub fn CFDictionaryContainsKey(theDict: CFDictionaryRef, key: *const c_void) -> Boolean; + pub fn CFDictionaryCreate(allocator: CFAllocatorRef, keys: *const *const c_void, values: *const *const c_void, + numValues: CFIndex, keyCallBacks: *const CFDictionaryKeyCallBacks, + valueCallBacks: *const CFDictionaryValueCallBacks) + -> CFDictionaryRef; + pub fn CFDictionaryGetCount(theDict: CFDictionaryRef) -> CFIndex; + pub fn CFDictionaryGetTypeID() -> CFTypeID; + pub fn CFDictionaryGetValueIfPresent(theDict: CFDictionaryRef, key: *const c_void, value: *mut *const c_void) + -> Boolean; +} diff --git a/core-foundation-sys/src/lib.rs b/core-foundation-sys/src/lib.rs new file mode 100644 index 0000000..1561b94 --- /dev/null +++ b/core-foundation-sys/src/lib.rs @@ -0,0 +1,23 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals, improper_ctypes)] + +extern crate libc; + +pub mod array; +pub mod base; +pub mod bundle; +pub mod data; +pub mod date; +pub mod dictionary; +pub mod number; +pub mod runloop; +pub mod set; +pub mod string; +pub mod url; diff --git a/core-foundation-sys/src/number.rs b/core-foundation-sys/src/number.rs new file mode 100644 index 0000000..31b91a0 --- /dev/null +++ b/core-foundation-sys/src/number.rs @@ -0,0 +1,59 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use base::{CFAllocatorRef, CFTypeID}; + +#[repr(C)] +struct __CFBoolean(c_void); + +pub type CFBooleanRef = *const __CFBoolean; + +pub type CFNumberType = u32; + +// members of enum CFNumberType +// static kCFNumberSInt8Type: CFNumberType = 1; +// static kCFNumberSInt16Type: CFNumberType = 2; +pub static kCFNumberSInt32Type: CFNumberType = 3; +pub static kCFNumberSInt64Type: CFNumberType = 4; +// static kCFNumberFloat32Type: CFNumberType = 5; +pub static kCFNumberFloat64Type: CFNumberType = 6; +// static kCFNumberCharType: CFNumberType = 7; +// static kCFNumberShortType: CFNumberType = 8; +// static kCFNumberIntType: CFNumberType = 9; +// static kCFNumberLongType: CFNumberType = 10; +// static kCFNumberLongLongType: CFNumberType = 11; +// static kCFNumberFloatType: CFNumberType = 12; +// static kCFNumberDoubleType: CFNumberType = 13; +// static kCFNumberCFIndexType: CFNumberType = 14; +// static kCFNumberNSIntegerType: CFNumberType = 15; +// static kCFNumberCGFloatType: CFNumberType = 16; +// static kCFNumberMaxType: CFNumberType = 16; + +#[repr(C)] +struct __CFNumber; + +pub type CFNumberRef = *const __CFNumber; + +extern { + /* + * CFNumber.h + */ + pub static kCFBooleanTrue: CFBooleanRef; + pub static kCFBooleanFalse: CFBooleanRef; + + pub fn CFBooleanGetTypeID() -> CFTypeID; + pub fn CFNumberCreate(allocator: CFAllocatorRef, theType: CFNumberType, valuePtr: *const c_void) + -> CFNumberRef; + //fn CFNumberGetByteSize + pub fn CFNumberGetValue(number: CFNumberRef, theType: CFNumberType, valuePtr: *mut c_void) -> bool; + //fn CFNumberCompare + pub fn CFNumberGetTypeID() -> CFTypeID; +} diff --git a/core-foundation-sys/src/runloop.rs b/core-foundation-sys/src/runloop.rs new file mode 100644 index 0000000..69d7579 --- /dev/null +++ b/core-foundation-sys/src/runloop.rs @@ -0,0 +1,164 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use array::CFArrayRef; +use base::{Boolean, CFIndex, CFTypeID, CFAllocatorRef, CFOptionFlags, CFHashCode, mach_port_t}; +use date::{CFAbsoluteTime, CFTimeInterval}; +use string::CFStringRef; + +#[repr(C)] +struct __CFRunLoop(c_void); + +pub type CFRunLoopRef = *const __CFRunLoop; + +#[repr(C)] +struct __CFRunLoopSource(c_void); + +pub type CFRunLoopSourceRef = *const __CFRunLoopSource; + +#[repr(C)] +struct __CFRunLoopObserver(c_void); + +pub type CFRunLoopObserverRef = *const __CFRunLoopObserver; + +// Reasons for CFRunLoopRunInMode() to Return +pub const kCFRunLoopRunFinished: i32 = 1; +pub const kCFRunLoopRunStopped: i32 = 2; +pub const kCFRunLoopRunTimedOut: i32 = 3; +pub const kCFRunLoopRunHandledSource: i32 = 4; + +// Run Loop Observer Activities +//typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { +pub type CFRunLoopActivity = CFOptionFlags; +pub const kCFRunLoopEntry: CFOptionFlags = 1 << 0; +pub const kCFRunLoopBeforeTimers: CFOptionFlags = 1 << 1; +pub const kCFRunLoopBeforeSources: CFOptionFlags = 1 << 2; +pub const kCFRunLoopBeforeWaiting: CFOptionFlags = 1 << 5; +pub const kCFRunLoopAfterWaiting: CFOptionFlags = 1 << 6; +pub const kCFRunLoopExit: CFOptionFlags = 1 << 7; +pub const kCFRunLoopAllActivities: CFOptionFlags = 0x0FFFFFFF; + +#[repr(C)] +pub struct CFRunLoopSourceContext { + pub version: CFIndex, + pub info: *mut c_void, + pub retain: extern "C" fn (info: *const c_void) -> *const c_void, + pub release: extern "C" fn (info: *const c_void), + pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + pub equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, + pub hash: extern "C" fn (info: *const c_void) -> CFHashCode, + pub schedule: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), + pub cancel: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), + pub perform: extern "C" fn (info: *const c_void), +} + +#[repr(C)] +pub struct CFRunLoopSourceContext1 { + pub version: CFIndex, + pub info: *mut c_void, + pub retain: extern "C" fn (info: *const c_void) -> *const c_void, + pub release: extern "C" fn (info: *const c_void), + pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + pub equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, + pub hash: extern "C" fn (info: *const c_void) -> CFHashCode, + // note that the following two fields are platform dependent in the C header, the ones here are for OS X + pub getPort: extern "C" fn (info: *mut c_void) -> mach_port_t, + pub perform: extern "C" fn (msg: *mut c_void, size: CFIndex, allocator: CFAllocatorRef, info: *mut c_void) -> *mut c_void, +} + +#[repr(C)] +pub struct CFRunLoopObserverContext { + pub version: CFIndex, + pub info: *mut c_void, + pub retain: extern "C" fn (info: *const c_void) -> *const c_void, + pub release: extern "C" fn (info: *const c_void), + pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, +} + +pub type CFRunLoopObserverCallBack = extern "C" fn (observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); + +#[repr(C)] +pub struct CFRunLoopTimerContext { + pub version: CFIndex, + pub info: *mut c_void, + pub retain: extern "C" fn (info: *const c_void) -> *const c_void, + pub release: extern "C" fn (info: *const c_void), + pub copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, +} + +pub type CFRunLoopTimerCallBack = extern "C" fn (timer: CFRunLoopTimerRef, info: *mut c_void); + +#[repr(C)] +struct __CFRunLoopTimer; + +pub type CFRunLoopTimerRef = *const __CFRunLoopTimer; + +extern { + /* + * CFRunLoop.h + */ + pub static kCFRunLoopDefaultMode: CFStringRef; + pub static kCFRunLoopCommonModes: CFStringRef; + pub fn CFRunLoopGetTypeID() -> CFTypeID; + pub fn CFRunLoopGetCurrent() -> CFRunLoopRef; + pub fn CFRunLoopGetMain() -> CFRunLoopRef; + pub fn CFRunLoopCopyCurrentMode(rl: CFRunLoopRef) -> CFStringRef; + pub fn CFRunLoopCopyAllModes(rl: CFRunLoopRef) -> CFArrayRef; + pub fn CFRunLoopAddCommonMode(rl: CFRunLoopRef, mode: CFStringRef); + pub fn CFRunLoopGetNextTimerFireDate(rl: CFRunLoopRef, mode: CFStringRef) -> CFAbsoluteTime; + pub fn CFRunLoopRun(); + pub fn CFRunLoopRunInMode(mode: CFStringRef, seconds: CFTimeInterval, returnAfterSourceHandled: Boolean) -> i32; + pub fn CFRunLoopIsWaiting(rl: CFRunLoopRef) -> Boolean; + pub fn CFRunLoopWakeUp(rl: CFRunLoopRef); + pub fn CFRunLoopStop(rl: CFRunLoopRef); + // fn CFRunLoopPerformBlock(rl: CFRunLoopRef, mode: CFTypeRef, block: void (^)(void)); + pub fn CFRunLoopContainsSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef) -> Boolean; + pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + pub fn CFRunLoopRemoveSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + pub fn CFRunLoopContainsObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef) -> Boolean; + pub fn CFRunLoopAddObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + pub fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + pub fn CFRunLoopContainsTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef) -> Boolean; + pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); + pub fn CFRunLoopRemoveTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); + + pub fn CFRunLoopSourceGetTypeID() -> CFTypeID; + pub fn CFRunLoopSourceCreate(allocator: CFAllocatorRef, order: CFIndex, context: *mut CFRunLoopSourceContext) -> CFRunLoopSourceRef; + pub fn CFRunLoopSourceGetOrder(source: CFRunLoopSourceRef) -> CFIndex; + pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); + pub fn CFRunLoopSourceIsValid(source: CFRunLoopSourceRef) -> Boolean; + pub fn CFRunLoopSourceGetContext(source: CFRunLoopSourceRef, context: *mut CFRunLoopSourceContext); + pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); + + pub fn CFRunLoopObserverGetTypeID() -> CFTypeID; + pub fn CFRunLoopObserverCreate(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, callout: CFRunLoopObserverCallBack, context: *mut CFRunLoopObserverContext) -> CFRunLoopObserverRef; + // fn CFRunLoopObserverCreateWithHandler(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, block: void (^) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) -> CFRunLoopObserverRef; + pub fn CFRunLoopObserverGetActivities(observer: CFRunLoopObserverRef) -> CFOptionFlags; + pub fn CFRunLoopObserverDoesRepeat(observer: CFRunLoopObserverRef) -> Boolean; + pub fn CFRunLoopObserverGetOrder(observer: CFRunLoopObserverRef) -> CFIndex; + pub fn CFRunLoopObserverInvalidate(observer: CFRunLoopObserverRef); + pub fn CFRunLoopObserverIsValid(observer: CFRunLoopObserverRef) -> Boolean; + pub fn CFRunLoopObserverGetContext(observer: CFRunLoopObserverRef, context: *mut CFRunLoopObserverContext); + + pub fn CFRunLoopTimerGetTypeID() -> CFTypeID; + pub fn CFRunLoopTimerCreate(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimerRef; + // fn CFRunLoopTimerCreateWithHandler(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, block: void (^) (CFRunLoopTimerRef timer)) -> CFRunLoopTimerRef; + pub fn CFRunLoopTimerGetNextFireDate(timer: CFRunLoopTimerRef) -> CFAbsoluteTime; + pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); + pub fn CFRunLoopTimerGetInterval(timer: CFRunLoopTimerRef) -> CFTimeInterval; + pub fn CFRunLoopTimerDoesRepeat(timer: CFRunLoopTimerRef) -> Boolean; + pub fn CFRunLoopTimerGetOrder(timer: CFRunLoopTimerRef) -> CFIndex; + pub fn CFRunLoopTimerInvalidate(timer: CFRunLoopTimerRef); + pub fn CFRunLoopTimerIsValid(timer: CFRunLoopTimerRef) -> Boolean; + pub fn CFRunLoopTimerGetContext(timer: CFRunLoopTimerRef, context: *mut CFRunLoopTimerContext); + pub fn CFRunLoopTimerGetTolerance(timer: CFRunLoopTimerRef) -> CFTimeInterval; + pub fn CFRunLoopTimerSetTolerance(timer: CFRunLoopTimerRef, tolerance: CFTimeInterval); +} diff --git a/core-foundation-sys/src/set.rs b/core-foundation-sys/src/set.rs new file mode 100644 index 0000000..e473da1 --- /dev/null +++ b/core-foundation-sys/src/set.rs @@ -0,0 +1,52 @@ +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::c_void; + +use base::{CFAllocatorRef, CFIndex, CFTypeID}; + +pub type CFSetRetainCallBack = *const u8; +pub type CFSetReleaseCallBack = *const u8; +pub type CFSetCopyDescriptionCallBack = *const u8; +pub type CFSetEqualCallBack = *const u8; +pub type CFSetHashCallBack = *const u8; + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct CFSetCallBacks { + pub version: CFIndex, + pub retain: CFSetRetainCallBack, + pub release: CFSetReleaseCallBack, + pub copyDescription: CFSetCopyDescriptionCallBack, + pub equal: CFSetEqualCallBack, + pub hash: CFSetHashCallBack, +} + +#[repr(C)] +struct __CFSet(c_void); + +pub type CFSetRef = *const __CFSet; + +extern { + /* + * CFSet.h + */ + + pub static kCFTypeSetCallBacks: CFSetCallBacks; + + /* Creating Sets */ + pub fn CFSetCreate(allocator: CFAllocatorRef, values: *const *const c_void, numValues: CFIndex, + callBacks: *const CFSetCallBacks) -> CFSetRef; + + /* Applying a Function to Set Members */ + //fn CFSetApplyFunction + + pub fn CFSetGetTypeID() -> CFTypeID; +} + diff --git a/src/string.rs b/core-foundation-sys/src/string.rs similarity index 65% rename from src/string.rs rename to core-foundation-sys/src/string.rs index 99bb397..76655da 100644 --- a/src/string.rs +++ b/core-foundation-sys/src/string.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 CFString { - unsafe { - TCFType::wrap_under_get_rule(self.0) - } - } -} - -impl Drop for CFString { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - -impl_TCFType!(CFString, CFStringRef, CFStringGetTypeID); - -impl FromStr for CFString { - type Err = (); - - /// See also CFString::new for a variant of this which does not return a Result - #[inline] - fn from_str(string: &str) -> Result { - Ok(CFString::new(string)) - } -} - -impl fmt::Display for CFString { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - unsafe { - // Do this without allocating if we can get away with it - let c_string = CFStringGetCStringPtr(self.0, kCFStringEncodingUTF8); - if c_string != ptr::null() { - let c_str = CStr::from_ptr(c_string); - fmt.write_str(str::from_utf8_unchecked(c_str.to_bytes())) - } else { - let char_len = self.char_len(); - - // First, ask how big the buffer ought to be. - let mut bytes_required: CFIndex = 0; - CFStringGetBytes(self.0, - CFRange::init(0, char_len), - kCFStringEncodingUTF8, - 0, - false as Boolean, - ptr::null_mut(), - 0, - &mut bytes_required); - - // Then, allocate the buffer and actually copy. - let mut buffer = Vec::with_capacity(bytes_required as usize); - for _ in (0..bytes_required) { buffer.push('\x00' as u8) } - - let mut bytes_used: CFIndex = 0; - let chars_written = CFStringGetBytes(self.0, - CFRange::init(0, char_len), - kCFStringEncodingUTF8, - 0, - false as Boolean, - buffer.as_mut_ptr(), - buffer.len().to_CFIndex(), - &mut bytes_used) as usize; - assert!(chars_written.to_CFIndex() == char_len); - - // This is dangerous; we over-allocate and null-terminate the string (during - // initialization). - assert!(bytes_used == buffer.len().to_CFIndex()); - fmt.write_str(str::from_utf8_unchecked(&buffer)) - } - } - } -} - -impl fmt::Debug for CFString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "\"{}\"", self) - } -} - - -impl CFString { - /// Creates a new `CFString` instance from a Rust string. - #[inline] - pub fn new(string: &str) -> CFString { - unsafe { - let string_ref = CFStringCreateWithBytes(kCFAllocatorDefault, - string.as_ptr(), - string.len().to_CFIndex(), - kCFStringEncodingUTF8, - false as Boolean, - kCFAllocatorNull); - CFString::wrap_under_create_rule(string_ref) - } - } - - /// Like `CFString::new`, but references a string that can be used as a backing store - /// by virtue of being statically allocated. - #[inline] - pub fn from_static_string(string: &'static str) -> CFString { - unsafe { - let string_ref = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, - string.as_ptr(), - string.len().to_CFIndex(), - kCFStringEncodingUTF8, - false as Boolean, - kCFAllocatorNull); - TCFType::wrap_under_create_rule(string_ref) - } - } - - /// Returns the number of characters in the string. - #[inline] - pub fn char_len(&self) -> CFIndex { - unsafe { - CFStringGetLength(self.0) - } - } -} - -#[link(name = "CoreFoundation", kind = "framework")] extern { /* * CFString.h @@ -342,20 +205,20 @@ extern { //fn CFStringCreateByCombiningStrings //fn CFStringCreateCopy //fn CFStringCreateFromExternalRepresentation - fn CFStringCreateWithBytes(alloc: CFAllocatorRef, - bytes: *const u8, - numBytes: CFIndex, - encoding: CFStringEncoding, - isExternalRepresentation: Boolean, - contentsDeallocator: CFAllocatorRef) - -> CFStringRef; - fn CFStringCreateWithBytesNoCopy(alloc: CFAllocatorRef, - bytes: *const u8, - numBytes: CFIndex, - encoding: CFStringEncoding, - isExternalRepresentation: Boolean, - contentsDeallocator: CFAllocatorRef) - -> CFStringRef; + pub fn CFStringCreateWithBytes(alloc: CFAllocatorRef, + bytes: *const u8, + numBytes: CFIndex, + encoding: CFStringEncoding, + isExternalRepresentation: Boolean, + contentsDeallocator: CFAllocatorRef) + -> CFStringRef; + pub fn CFStringCreateWithBytesNoCopy(alloc: CFAllocatorRef, + bytes: *const u8, + numBytes: CFIndex, + encoding: CFStringEncoding, + isExternalRepresentation: Boolean, + contentsDeallocator: CFAllocatorRef) + -> CFStringRef; //fn CFStringCreateWithCharacters //fn CFStringCreateWithCharactersNoCopy //fn CFStringCreateWithCString @@ -383,24 +246,24 @@ extern { /* Accessing Characters */ //fn CFStringCreateExternalRepresentation - fn CFStringGetBytes(theString: CFStringRef, - range: CFRange, - encoding: CFStringEncoding, - lossByte: u8, - isExternalRepresentation: Boolean, - buffer: *mut u8, - maxBufLen: CFIndex, - usedBufLen: *mut CFIndex) - -> CFIndex; + pub fn CFStringGetBytes(theString: CFStringRef, + range: CFRange, + encoding: CFStringEncoding, + lossByte: u8, + isExternalRepresentation: Boolean, + buffer: *mut u8, + maxBufLen: CFIndex, + usedBufLen: *mut CFIndex) + -> CFIndex; //fn CFStringGetCharacterAtIndex //fn CFStringGetCharacters //fn CFStringGetCharactersPtr //fn CFStringGetCharacterFromInlineBuffer //fn CFStringGetCString - fn CFStringGetCStringPtr(theString: CFStringRef, - encoding: CFStringEncoding) - -> *const libc::c_char; - fn CFStringGetLength(theString: CFStringRef) -> CFIndex; + pub fn CFStringGetCStringPtr(theString: CFStringRef, + encoding: CFStringEncoding) + -> *const c_char; + pub fn CFStringGetLength(theString: CFStringRef) -> CFIndex; //fn CFStringGetPascalString //fn CFStringGetPascalStringPtr //fn CFStringGetRangeOfComposedCharactersAtIndex @@ -432,7 +295,7 @@ extern { /* Getting String Properties */ //fn CFShowStr - fn CFStringGetTypeID() -> CFTypeID; + pub fn CFStringGetTypeID() -> CFTypeID; /* String File System Representations */ //fn CFStringCreateWithFileSystemRepresentation @@ -448,11 +311,3 @@ extern { //fn CFStringIsSurrogateHighCharacter //fn CFStringIsSurrogateLowCharacter } - -#[test] -fn string_and_back() { - let original = "The quick brown fox jumped over the slow lazy dog."; - let cfstr = CFString::from_static_string(original); - let converted = cfstr.to_string(); - assert!(converted == original); -} diff --git a/src/url.rs b/core-foundation-sys/src/url.rs similarity index 75% rename from src/url.rs rename to core-foundation-sys/src/url.rs index c6c5708..53fc456 100644 --- a/src/url.rs +++ b/core-foundation-sys/src/url.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +use libc::c_void; -//! A URL type for Core Foundation. - -#![allow(non_upper_case_globals)] - -use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFRelease}; -use base::{Boolean, CFTypeID, TCFType}; -use base::{kCFAllocatorDefault}; -use string::{CFString, CFStringRef}; - -use std::fmt; -use std::mem; +use base::{CFOptionFlags, CFIndex, CFAllocatorRef, Boolean, CFTypeID}; +use string::CFStringRef; #[repr(C)] -struct __CFURL; +struct __CFURL(c_void); pub type CFURLRef = *const __CFURL; -pub struct CFURL(CFURLRef); - -impl Drop for CFURL { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - -impl_TCFType!(CFURL, CFURLRef, CFURLGetTypeID); - -impl fmt::Debug for CFURL { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - unsafe { - let string: CFString = TCFType::wrap_under_get_rule(CFURLGetString(self.0)); - write!(f, "{}", string.to_string()) - } - } -} - -impl CFURL { - pub fn from_file_system_path(filePath: CFString, pathStyle: CFURLPathStyle, isDirectory: bool) -> CFURL { - unsafe { - let url_ref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath.as_concrete_TypeRef(), pathStyle, isDirectory as u8); - TCFType::wrap_under_create_rule(url_ref) - } - } - - pub fn get_string(&self) -> CFString { - unsafe { - TCFType::wrap_under_get_rule(CFURLGetString(self.0)) - } - } -} - -type CFURLBookmarkCreationOptions = CFOptionFlags; +pub type CFURLBookmarkCreationOptions = CFOptionFlags; pub type CFURLPathStyle = CFIndex; @@ -70,7 +25,6 @@ pub const kCFURLPOSIXPathStyle: CFURLPathStyle = 0; pub const kCFURLHFSPathStyle: CFURLPathStyle = 1; pub const kCFURLWindowsPathStyle: CFURLPathStyle = 2; - // static kCFURLBookmarkCreationPreferFileIDResolutionMask: CFURLBookmarkCreationOptions = // (1 << 8) as u32; // static kCFURLBookmarkCreationMinimalBookmarkMask: CFURLBookmarkCreationOptions = @@ -84,7 +38,6 @@ pub const kCFURLWindowsPathStyle: CFURLPathStyle = 2; // TODO: there are a lot of missing keys and constants. Add if you are bored or need them. -#[link(name = "CoreFoundation", kind = "framework")] extern { /* * CFURL.h @@ -141,7 +94,7 @@ extern { //fn CFURLCreateFromFSRef //fn CFURLCreateWithBytes //fn CFURLCreateWithFileSystemPath - fn CFURLCreateWithFileSystemPath(allocator: CFAllocatorRef, filePath: CFStringRef, pathStyle: CFURLPathStyle, isDirectory: Boolean) -> CFURLRef; + pub fn CFURLCreateWithFileSystemPath(allocator: CFAllocatorRef, filePath: CFStringRef, pathStyle: CFURLPathStyle, isDirectory: Boolean) -> CFURLRef; //fn CFURLCreateWithFileSystemPathRelativeToBase //fn CFURLCreateWithString(allocator: CFAllocatorRef, urlString: CFStringRef, // baseURL: CFURLRef) -> CFURLRef; @@ -173,13 +126,13 @@ extern { //fn CFURLCreateStringByReplacingPercentEscapesUsingEncoding //fn CFURLGetFileSystemRepresentation //fn CFURLGetFSRef - fn CFURLGetString(anURL: CFURLRef) -> CFStringRef; + pub fn CFURLGetString(anURL: CFURLRef) -> CFStringRef; /* Getting URL Properties */ //fn CFURLGetBaseURL(anURL: CFURLRef) -> CFURLRef; //fn CFURLGetBytes //fn CFURLGetByteRangeForComponent - fn CFURLGetTypeID() -> CFTypeID; + pub fn CFURLGetTypeID() -> CFTypeID; //fn CFURLResourceIsReachable /* Getting and Setting File System Resource Properties */ @@ -201,11 +154,3 @@ extern { //fn CFURLStartAccessingSecurityScopedResource //fn CFURLStopAccessingSecurityScopedResource } - -#[test] -fn file_url_from_path() { - let path = "/usr/local/foo/"; - let cfstr_path = CFString::from_static_string(path); - let cfurl = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true); - assert!(cfurl.get_string().to_string() == "file:///usr/local/foo/"); -} diff --git a/Cargo.toml b/core-foundation/Cargo.toml similarity index 81% rename from Cargo.toml rename to core-foundation/Cargo.toml index 9f07bae..122b69a 100644 --- a/Cargo.toml +++ b/core-foundation/Cargo.toml @@ -8,4 +8,5 @@ authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" [dependencies] -libc = "*" +libc = "0.1" +core-foundation-sys = { path = "../core-foundation-sys" } diff --git a/src/array.rs b/core-foundation/src/array.rs similarity index 69% rename from src/array.rs rename to core-foundation/src/array.rs index 0a47a2c..757725a 100644 --- a/src/array.rs +++ b/core-foundation/src/array.rs @@ -9,39 +9,13 @@ //! Heterogeneous immutable arrays. -use base::{CFAllocatorRef, CFIndex, CFIndexConvertible, CFRelease}; -use base::{CFTypeID, CFTypeRef, TCFType}; -use base::{kCFAllocatorDefault}; +pub use core_foundation_sys::array::*; +use core_foundation_sys::base::{CFIndex, CFRelease}; +use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; use libc::c_void; use std::mem; -/// FIXME(pcwalton): This is wrong. -pub type CFArrayRetainCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayReleaseCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayCopyDescriptionCallBack = *const u8; - -/// FIXME(pcwalton): This is wrong. -pub type CFArrayEqualCallBack = *const u8; - -#[allow(dead_code)] -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CFArrayCallBacks { - version: CFIndex, - retain: CFArrayRetainCallBack, - release: CFArrayReleaseCallBack, - copyDescription: CFArrayCopyDescriptionCallBack, - equal: CFArrayEqualCallBack, -} - -#[repr(C)] -struct __CFArray; - -pub type CFArrayRef = *const __CFArray; +use base::{CFIndexConvertible, TCFType}; /// A heterogeneous immutable array. pub struct CFArray(CFArrayRef); @@ -126,28 +100,6 @@ impl<'a> IntoIterator for &'a CFArray { } } -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFArray.h - */ - static kCFTypeArrayCallBacks: CFArrayCallBacks; - - fn CFArrayCreate(allocator: CFAllocatorRef, values: *const *const c_void, - numValues: CFIndex, callBacks: *const CFArrayCallBacks) -> CFArrayRef; - // CFArrayCreateCopy - // CFArrayBSearchValues - // CFArrayContainsValue - fn CFArrayGetCount(theArray: CFArrayRef) -> CFIndex; - // CFArrayGetCountOfValue - // CFArrayGetFirstIndexOfValue - // CFArrayGetLastIndexOfValue - // CFArrayGetValues - fn CFArrayGetValueAtIndex(theArray: CFArrayRef, idx: CFIndex) -> *const c_void; - // CFArrayApplyFunction - fn CFArrayGetTypeID() -> CFTypeID; -} - #[test] fn should_box_and_unbox() { use number::{CFNumber, number}; diff --git a/src/base.rs b/core-foundation/src/base.rs similarity index 69% rename from src/base.rs rename to core-foundation/src/base.rs index fb1dadf..3f4bcea 100644 --- a/src/base.rs +++ b/core-foundation/src/base.rs @@ -7,14 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use libc::{c_long, c_ulong, c_uint}; - -pub type Boolean = u8; - -pub type CFIndex = c_long; - -#[allow(non_camel_case_types)] -pub type mach_port_t = c_uint; +pub use core_foundation_sys::base::*; pub trait CFIndexConvertible { /// Always use this method to construct a `CFIndex` value. It performs bounds checking to @@ -33,44 +26,6 @@ impl CFIndexConvertible for usize { } } -pub type CFOptionFlags = u32; - -#[allow(dead_code)] -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CFRange { - location: CFIndex, - length: CFIndex -} - -impl CFRange { - pub fn init(offset: CFIndex, length: CFIndex) -> CFRange { - CFRange { - location: offset, - length: length, - } - } -} - -#[repr(C)] -struct __CFAllocator; - -pub type CFAllocatorRef = *const __CFAllocator; - -#[repr(C)] -struct __CFNull; - -pub type CFNullRef = *const __CFNull; - -pub type CFHashCode = c_ulong; - -pub type CFTypeID = c_ulong; - -#[repr(C)] -struct __CFType; - -pub type CFTypeRef = *const __CFType; - /// Superclass of all Core Foundation objects. pub struct CFType(CFTypeRef); @@ -185,40 +140,3 @@ impl TCFType for CFType { true } } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFBase.h - */ - - /* CFAllocator Reference */ - // N.B. Many CFAllocator functions and constants are omitted here. - pub static kCFAllocatorDefault: CFAllocatorRef; - pub static kCFAllocatorSystemDefault: CFAllocatorRef; - pub static kCFAllocatorMalloc: CFAllocatorRef; - pub static kCFAllocatorMallocZone: CFAllocatorRef; - pub static kCFAllocatorNull: CFAllocatorRef; - pub static kCFAllocatorUseContext: CFAllocatorRef; - - /* CFNull Reference */ - - pub static kCFNull: CFNullRef; - - /* CFType Reference */ - - //fn CFCopyDescription - //fn CFCopyTypeIDDescription - //fn CFEqual - //fn CFGetAllocator - pub fn CFGetRetainCount(cf: CFTypeRef) -> CFIndex; - pub fn CFGetTypeID(cf: CFTypeRef) -> CFTypeID; - pub fn CFHash(cf: CFTypeRef) -> CFHashCode; - //fn CFMakeCollectable - pub fn CFRelease(cf: CFTypeRef); - pub fn CFRetain(cf: CFTypeRef) -> CFTypeRef; - pub fn CFShow(obj: CFTypeRef); - - /* Base Utilities Reference */ - // N.B. Some things missing here. -} diff --git a/src/boolean.rs b/core-foundation/src/boolean.rs similarity index 76% rename from src/boolean.rs rename to core-foundation/src/boolean.rs index 9ededa8..20f4630 100644 --- a/src/boolean.rs +++ b/core-foundation/src/boolean.rs @@ -9,15 +9,11 @@ //! A Boolean type. -use base::{CFRelease, CFTypeID, TCFType}; +use core_foundation_sys::base::{CFRelease}; +pub use core_foundation_sys::number::{CFBooleanRef, CFBooleanGetTypeID, kCFBooleanTrue, kCFBooleanFalse}; use std::mem; -pub type Boolean = u32; - -#[repr(C)] -struct __CFBoolean; - -pub type CFBooleanRef = *const __CFBoolean; +use base::TCFType; /// A Boolean type. /// @@ -47,12 +43,3 @@ impl CFBoolean { } } } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - static kCFBooleanTrue: CFBooleanRef; - static kCFBooleanFalse: CFBooleanRef; - - fn CFBooleanGetTypeID() -> CFTypeID; -} - diff --git a/src/bundle.rs b/core-foundation/src/bundle.rs similarity index 59% rename from src/bundle.rs rename to core-foundation/src/bundle.rs index 76edb33..2f42b26 100644 --- a/src/bundle.rs +++ b/core-foundation/src/bundle.rs @@ -9,16 +9,11 @@ //! Core Foundation Bundle Type -use base::{CFRelease, CFTypeID, TCFType}; +pub use core_foundation_sys::bundle::*; +use core_foundation_sys::base::CFRelease; use std::mem; -use string::CFStringRef; -use libc::c_void; - -#[repr(C)] -struct __CFBundle; - -pub type CFBundleRef = *const __CFBundle; +use base::{TCFType}; /// A Bundle type. pub struct CFBundle(CFBundleRef); @@ -32,17 +27,3 @@ impl Drop for CFBundle { } impl_TCFType!(CFBundle, CFBundleRef, CFBundleGetTypeID); - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFBundle.h - */ - - - pub fn CFBundleGetBundleWithIdentifier(bundleID: CFStringRef) -> CFBundleRef; - pub fn CFBundleGetFunctionPointerForName(bundle: CFBundleRef, function_name: CFStringRef) -> *const c_void; - - fn CFBundleGetTypeID() -> CFTypeID; -} - diff --git a/src/data.rs b/core-foundation/src/data.rs similarity index 74% rename from src/data.rs rename to core-foundation/src/data.rs index 9c8ace9..9b6a65f 100644 --- a/src/data.rs +++ b/core-foundation/src/data.rs @@ -9,17 +9,14 @@ //! Core Foundation byte buffers. -use base::{CFAllocatorRef, CFIndex, CFIndexConvertible, CFRelease}; -use base::{CFTypeID, TCFType, kCFAllocatorDefault}; - +pub use core_foundation_sys::data::*; +use core_foundation_sys::base::{CFIndex, CFRelease}; +use core_foundation_sys::base::{kCFAllocatorDefault}; use std::mem; use std::ops::Deref; use std::slice; -#[repr(C)] -struct __CFData; - -pub type CFDataRef = *const __CFData; +use base::{CFIndexConvertible, TCFType}; /// A byte buffer. pub struct CFData(CFDataRef); @@ -70,18 +67,3 @@ impl Deref for CFData { self.bytes() } } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFData.h - */ - - fn CFDataCreate(allocator: CFAllocatorRef, - bytes: *const u8, length: CFIndex) -> CFDataRef; - //fn CFDataFind - fn CFDataGetBytePtr(theData: CFDataRef) -> *const u8; - fn CFDataGetLength(theData: CFDataRef) -> CFIndex; - - fn CFDataGetTypeID() -> CFTypeID; -} diff --git a/src/dictionary.rs b/core-foundation/src/dictionary.rs similarity index 58% rename from src/dictionary.rs rename to core-foundation/src/dictionary.rs index e2fbd7c..9540fba 100644 --- a/src/dictionary.rs +++ b/core-foundation/src/dictionary.rs @@ -9,47 +9,14 @@ //! Dictionaries of key-value pairs. -use base::{Boolean, CFAllocatorRef, CFIndex, CFIndexConvertible, CFRelease}; -use base::{CFType, CFTypeID, CFTypeRef, TCFType, kCFAllocatorDefault}; - +pub use core_foundation_sys::dictionary::*; +use core_foundation_sys::base::CFRelease; +use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; use libc::c_void; use std::mem; use std::ptr; -pub type CFDictionaryApplierFunction = *const u8; -pub type CFDictionaryCopyDescriptionCallBack = *const u8; -pub type CFDictionaryEqualCallBack = *const u8; -pub type CFDictionaryHashCallBack = *const u8; -pub type CFDictionaryReleaseCallBack = *const u8; -pub type CFDictionaryRetainCallBack = *const u8; - -#[allow(dead_code)] -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CFDictionaryKeyCallBacks { - version: CFIndex, - retain: CFDictionaryRetainCallBack, - release: CFDictionaryReleaseCallBack, - copyDescription: CFDictionaryCopyDescriptionCallBack, - equal: CFDictionaryEqualCallBack, - hash: CFDictionaryHashCallBack -} - -#[allow(dead_code)] -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CFDictionaryValueCallBacks { - version: CFIndex, - retain: CFDictionaryRetainCallBack, - release: CFDictionaryReleaseCallBack, - copyDescription: CFDictionaryCopyDescriptionCallBack, - equal: CFDictionaryEqualCallBack -} - -#[repr(C)] -struct __CFDictionary; - -pub type CFDictionaryRef = *const __CFDictionary; +use base::{CFType, CFIndexConvertible, TCFType}; /// An immutable dictionary of key-value pairs. pub struct CFDictionary(CFDictionaryRef); @@ -130,23 +97,3 @@ impl CFDictionary { TCFType::wrap_under_get_rule(value) } } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFDictionary.h - */ - - static kCFTypeDictionaryKeyCallBacks: CFDictionaryKeyCallBacks; - static kCFTypeDictionaryValueCallBacks: CFDictionaryValueCallBacks; - - fn CFDictionaryContainsKey(theDict: CFDictionaryRef, key: *const c_void) -> Boolean; - fn CFDictionaryCreate(allocator: CFAllocatorRef, keys: *const *const c_void, values: *const *const c_void, - numValues: CFIndex, keyCallBacks: *const CFDictionaryKeyCallBacks, - valueCallBacks: *const CFDictionaryValueCallBacks) - -> CFDictionaryRef; - fn CFDictionaryGetCount(theDict: CFDictionaryRef) -> CFIndex; - fn CFDictionaryGetTypeID() -> CFTypeID; - fn CFDictionaryGetValueIfPresent(theDict: CFDictionaryRef, key: *const c_void, value: *mut *const c_void) - -> Boolean; -} diff --git a/src/lib.rs b/core-foundation/src/lib.rs similarity index 87% rename from src/lib.rs rename to core-foundation/src/lib.rs index 569a2e0..39b533a 100644 --- a/src/lib.rs +++ b/core-foundation/src/lib.rs @@ -6,12 +6,9 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![crate_name = "core_foundation"] -#![crate_type = "rlib"] - #![allow(non_snake_case)] +extern crate core_foundation_sys; extern crate libc; #[macro_export] @@ -25,12 +22,12 @@ macro_rules! impl_TCFType { #[inline] unsafe fn wrap_under_get_rule(reference: $raw) -> $ty { - let reference = mem::transmute($crate::base::CFRetain(mem::transmute(reference))); + let reference = mem::transmute(::core_foundation_sys::base::CFRetain(mem::transmute(reference))); $crate::base::TCFType::wrap_under_create_rule(reference) } #[inline] - fn as_CFTypeRef(&self) -> $crate::base::CFTypeRef { + fn as_CFTypeRef(&self) -> ::core_foundation_sys::base::CFTypeRef { unsafe { mem::transmute(self.as_concrete_TypeRef()) } @@ -42,7 +39,7 @@ macro_rules! impl_TCFType { } #[inline] - fn type_id() -> $crate::base::CFTypeID { + fn type_id() -> ::core_foundation_sys::base::CFTypeID { unsafe { $ty_id() } @@ -55,13 +52,13 @@ pub mod array; pub mod base; pub mod boolean; pub mod data; +pub use core_foundation_sys::date; // back compat pub mod dictionary; pub mod number; pub mod set; pub mod string; pub mod url; pub mod bundle; -pub mod date; pub mod runloop; #[cfg(test)] diff --git a/src/number.rs b/core-foundation/src/number.rs similarity index 61% rename from src/number.rs rename to core-foundation/src/number.rs index 198dbad..771c75e 100644 --- a/src/number.rs +++ b/core-foundation/src/number.rs @@ -9,39 +9,11 @@ //! Immutable numbers. -#![allow(non_upper_case_globals)] - -use base::{CFAllocatorRef, CFRelease, CFTypeID}; -use base::{TCFType, kCFAllocatorDefault}; - -use libc::c_void; +use core_foundation_sys::base::{CFRelease, kCFAllocatorDefault}; +pub use core_foundation_sys::number::*; use std::mem; -pub type CFNumberType = u32; - -// members of enum CFNumberType -// static kCFNumberSInt8Type: CFNumberType = 1; -// static kCFNumberSInt16Type: CFNumberType = 2; -static kCFNumberSInt32Type: CFNumberType = 3; -static kCFNumberSInt64Type: CFNumberType = 4; -// static kCFNumberFloat32Type: CFNumberType = 5; -static kCFNumberFloat64Type: CFNumberType = 6; -// static kCFNumberCharType: CFNumberType = 7; -// static kCFNumberShortType: CFNumberType = 8; -// static kCFNumberIntType: CFNumberType = 9; -// static kCFNumberLongType: CFNumberType = 10; -// static kCFNumberLongLongType: CFNumberType = 11; -// static kCFNumberFloatType: CFNumberType = 12; -// static kCFNumberDoubleType: CFNumberType = 13; -// static kCFNumberCFIndexType: CFNumberType = 14; -// static kCFNumberNSIntegerType: CFNumberType = 15; -// static kCFNumberCGFloatType: CFNumberType = 16; -// static kCFNumberMaxType: CFNumberType = 16; - -#[repr(C)] -struct __CFNumber; - -pub type CFNumberRef = *const __CFNumber; +use base::{TCFType}; /// An immutable numeric value. pub struct CFNumber(CFNumberRef); @@ -111,18 +83,3 @@ impl CFNumber { pub fn number(value: i64) -> CFNumber { CFNumber::from_i64(value) } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFNumber.h - */ - - - fn CFNumberCreate(allocator: CFAllocatorRef, theType: CFNumberType, valuePtr: *const c_void) - -> CFNumberRef; - //fn CFNumberGetByteSize - fn CFNumberGetValue(number: CFNumberRef, theType: CFNumberType, valuePtr: *mut c_void) -> bool; - //fn CFNumberCompare - fn CFNumberGetTypeID() -> CFTypeID; -} diff --git a/core-foundation/src/runloop.rs b/core-foundation/src/runloop.rs new file mode 100644 index 0000000..ccf7b73 --- /dev/null +++ b/core-foundation/src/runloop.rs @@ -0,0 +1,141 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_upper_case_globals)] + +pub use core_foundation_sys::runloop::*; +use core_foundation_sys::base::{CFIndex, CFRelease}; +use core_foundation_sys::base::{kCFAllocatorDefault, CFOptionFlags}; +use core_foundation_sys::string::CFStringRef; +use core_foundation_sys::date::{CFAbsoluteTime, CFTimeInterval}; +use std::mem; + +use base::{TCFType}; +use string::{CFString}; + +pub struct CFRunLoop(CFRunLoopRef); + +impl Drop for CFRunLoop { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFRunLoop, CFRunLoopRef, CFRunLoopGetTypeID); + +impl CFRunLoop { + pub fn get_current() -> CFRunLoop { + unsafe { + let run_loop_ref = CFRunLoopGetCurrent(); + TCFType::wrap_under_get_rule(run_loop_ref) + } + } + + pub fn get_main() -> CFRunLoop { + unsafe { + let run_loop_ref = CFRunLoopGetMain(); + TCFType::wrap_under_get_rule(run_loop_ref) + } + } + + pub fn run_current() { + unsafe { + CFRunLoopRun(); + } + } + + pub fn stop(&self) { + unsafe { + CFRunLoopStop(self.0); + } + } + + pub fn current_mode(&self) -> Option { + unsafe { + let string_ref = CFRunLoopCopyCurrentMode(self.0); + if string_ref.is_null() { + return None; + } + + let cf_string: CFString = TCFType::wrap_under_create_rule(string_ref); + Some(cf_string.to_string()) + } + } + + pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) -> bool { + unsafe { + CFRunLoopContainsTimer(self.0, timer.0, mode) != 0 + } + } + + pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) { + unsafe { + CFRunLoopAddTimer(self.0, timer.0, mode); + } + } + +} + +pub struct CFRunLoopTimer(CFRunLoopTimerRef); + +impl Drop for CFRunLoopTimer { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFRunLoopTimer, CFRunLoopTimerRef, CFRunLoopTimerGetTypeID); + +impl CFRunLoopTimer { + pub fn new(fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimer { + unsafe { + let timer_ref = CFRunLoopTimerCreate(kCFAllocatorDefault, fireDate, interval, flags, order, callout, context); + TCFType::wrap_under_create_rule(timer_ref) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + use core_foundation_sys::date::{CFAbsoluteTime, CFAbsoluteTimeGetCurrent}; + use std::mem; + use libc::c_void; + + #[test] + fn wait_200_milliseconds() { + let run_loop = CFRunLoop::get_current(); + let mut now = unsafe { CFAbsoluteTimeGetCurrent() }; + let mut context = unsafe { CFRunLoopTimerContext { + version: 0, + info: mem::transmute(&mut now), + retain: mem::zeroed(), + release: mem::zeroed(), + copyDescription: mem::zeroed(), + } }; + + + let run_loop_timer = CFRunLoopTimer::new(now + 0.20f64, 0f64, 0, 0, timer_popped, &mut context); + run_loop.add_timer(&run_loop_timer, kCFRunLoopDefaultMode); + + CFRunLoop::run_current(); + } + + extern "C" fn timer_popped(_timer: CFRunLoopTimerRef, _info: *mut c_void) { + let previous_now_ptr: *const CFAbsoluteTime = unsafe { mem::transmute(_info) }; + let previous_now = unsafe { *previous_now_ptr }; + let now = unsafe { CFAbsoluteTimeGetCurrent() }; + assert!(now - previous_now > 0.19 && now - previous_now < 0.21); + CFRunLoop::get_current().stop(); + } +} diff --git a/src/set.rs b/core-foundation/src/set.rs similarity index 52% rename from src/set.rs rename to core-foundation/src/set.rs index b5e26b8..8224a20 100644 --- a/src/set.rs +++ b/core-foundation/src/set.rs @@ -9,34 +9,13 @@ //! An immutable bag of elements. -use base::{CFAllocatorRef, CFIndex, CFIndexConvertible, CFRelease}; -use base::{CFTypeID, CFTypeRef, TCFType, kCFAllocatorDefault}; +pub use core_foundation_sys::set::*; +use core_foundation_sys::base::CFRelease; +use core_foundation_sys::base::{CFTypeRef, kCFAllocatorDefault}; -use libc::c_void; -use std::mem; - -pub type CFSetRetainCallBack = *const u8; -pub type CFSetReleaseCallBack = *const u8; -pub type CFSetCopyDescriptionCallBack = *const u8; -pub type CFSetEqualCallBack = *const u8; -pub type CFSetHashCallBack = *const u8; - -#[allow(dead_code)] -#[repr(C)] -#[derive(Clone, Copy)] -pub struct CFSetCallBacks { - version: CFIndex, - retain: CFSetRetainCallBack, - release: CFSetReleaseCallBack, - copyDescription: CFSetCopyDescriptionCallBack, - equal: CFSetEqualCallBack, - hash: CFSetHashCallBack, -} +use base::{CFIndexConvertible, TCFType}; -#[repr(C)] -struct __CFSet; - -pub type CFSetRef = *const __CFSet; +use std::mem; /// An immutable bag of elements. pub struct CFSet(CFSetRef); @@ -64,22 +43,3 @@ impl CFSet { } } } - -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFSet.h - */ - - static kCFTypeSetCallBacks: CFSetCallBacks; - - /* Creating Sets */ - fn CFSetCreate(allocator: CFAllocatorRef, values: *const *const c_void, numValues: CFIndex, - callBacks: *const CFSetCallBacks) -> CFSetRef; - - /* Applying a Function to Set Members */ - //fn CFSetApplyFunction - - fn CFSetGetTypeID() -> CFTypeID; -} - diff --git a/core-foundation/src/string.rs b/core-foundation/src/string.rs new file mode 100644 index 0000000..37f06b4 --- /dev/null +++ b/core-foundation/src/string.rs @@ -0,0 +1,155 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Immutable strings. + +pub use core_foundation_sys::string::*; + +use base::{CFIndexConvertible, TCFType}; + +use core_foundation_sys::base::{Boolean, CFIndex, CFRange, CFRelease}; +use core_foundation_sys::base::{kCFAllocatorDefault, kCFAllocatorNull}; +use std::fmt; +use std::str::{self, FromStr}; +use std::mem; +use std::ptr; +use std::vec::Vec; +use std::ffi::CStr; + +/// An immutable string in one of a variety of encodings. +pub struct CFString(CFStringRef); + +impl Clone for CFString { + #[inline] + fn clone(&self) -> CFString { + unsafe { + TCFType::wrap_under_get_rule(self.0) + } + } +} + +impl Drop for CFString { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFString, CFStringRef, CFStringGetTypeID); + +impl FromStr for CFString { + type Err = (); + + /// See also CFString::new for a variant of this which does not return a Result + #[inline] + fn from_str(string: &str) -> Result { + Ok(CFString::new(string)) + } +} + +impl fmt::Display for CFString { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + unsafe { + // Do this without allocating if we can get away with it + let c_string = CFStringGetCStringPtr(self.0, kCFStringEncodingUTF8); + if c_string != ptr::null() { + let c_str = CStr::from_ptr(c_string); + fmt.write_str(str::from_utf8_unchecked(c_str.to_bytes())) + } else { + let char_len = self.char_len(); + + // First, ask how big the buffer ought to be. + let mut bytes_required: CFIndex = 0; + CFStringGetBytes(self.0, + CFRange { location: 0, length: char_len }, + kCFStringEncodingUTF8, + 0, + false as Boolean, + ptr::null_mut(), + 0, + &mut bytes_required); + + // Then, allocate the buffer and actually copy. + let mut buffer = Vec::with_capacity(bytes_required as usize); + for _ in (0..bytes_required) { buffer.push('\x00' as u8) } + + let mut bytes_used: CFIndex = 0; + let chars_written = CFStringGetBytes(self.0, + CFRange { location: 0, length: char_len }, + kCFStringEncodingUTF8, + 0, + false as Boolean, + buffer.as_mut_ptr(), + buffer.len().to_CFIndex(), + &mut bytes_used) as usize; + assert!(chars_written.to_CFIndex() == char_len); + + // This is dangerous; we over-allocate and null-terminate the string (during + // initialization). + assert!(bytes_used == buffer.len().to_CFIndex()); + fmt.write_str(str::from_utf8_unchecked(&buffer)) + } + } + } +} + +impl fmt::Debug for CFString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "\"{}\"", self) + } +} + + +impl CFString { + /// Creates a new `CFString` instance from a Rust string. + #[inline] + pub fn new(string: &str) -> CFString { + unsafe { + let string_ref = CFStringCreateWithBytes(kCFAllocatorDefault, + string.as_ptr(), + string.len().to_CFIndex(), + kCFStringEncodingUTF8, + false as Boolean, + kCFAllocatorNull); + CFString::wrap_under_create_rule(string_ref) + } + } + + /// Like `CFString::new`, but references a string that can be used as a backing store + /// by virtue of being statically allocated. + #[inline] + pub fn from_static_string(string: &'static str) -> CFString { + unsafe { + let string_ref = CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, + string.as_ptr(), + string.len().to_CFIndex(), + kCFStringEncodingUTF8, + false as Boolean, + kCFAllocatorNull); + TCFType::wrap_under_create_rule(string_ref) + } + } + + /// Returns the number of characters in the string. + #[inline] + pub fn char_len(&self) -> CFIndex { + unsafe { + CFStringGetLength(self.0) + } + } +} + +#[test] +fn string_and_back() { + let original = "The quick brown fox jumped over the slow lazy dog."; + let cfstr = CFString::from_static_string(original); + let converted = cfstr.to_string(); + assert!(converted == original); +} diff --git a/core-foundation/src/url.rs b/core-foundation/src/url.rs new file mode 100644 index 0000000..47f44cb --- /dev/null +++ b/core-foundation/src/url.rs @@ -0,0 +1,64 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A URL type for Core Foundation. + +pub use core_foundation_sys::url::*; + +use base::{TCFType}; +use string::{CFString}; + +use core_foundation_sys::base::{kCFAllocatorDefault, CFRelease}; +use std::fmt; +use std::mem; + +pub struct CFURL(CFURLRef); + +impl Drop for CFURL { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl_TCFType!(CFURL, CFURLRef, CFURLGetTypeID); + +impl fmt::Debug for CFURL { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + unsafe { + let string: CFString = TCFType::wrap_under_get_rule(CFURLGetString(self.0)); + write!(f, "{}", string.to_string()) + } + } +} + +impl CFURL { + pub fn from_file_system_path(filePath: CFString, pathStyle: CFURLPathStyle, isDirectory: bool) -> CFURL { + unsafe { + let url_ref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath.as_concrete_TypeRef(), pathStyle, isDirectory as u8); + TCFType::wrap_under_create_rule(url_ref) + } + } + + pub fn get_string(&self) -> CFString { + unsafe { + TCFType::wrap_under_get_rule(CFURLGetString(self.0)) + } + } +} + +#[test] +fn file_url_from_path() { + let path = "/usr/local/foo/"; + let cfstr_path = CFString::from_static_string(path); + let cfurl = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true); + assert!(cfurl.get_string().to_string() == "file:///usr/local/foo/"); +} diff --git a/src/runloop.rs b/src/runloop.rs deleted file mode 100644 index b0782a2..0000000 --- a/src/runloop.rs +++ /dev/null @@ -1,293 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(non_upper_case_globals)] - -use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFRelease}; -use base::{CFTypeID, TCFType, CFHashCode, mach_port_t}; -use base::{kCFAllocatorDefault}; -use base::{Boolean}; -use array::{CFArrayRef}; -use string::{CFString, CFStringRef}; -use date::{CFAbsoluteTime, CFTimeInterval}; -use libc::c_void; -use std::mem; - -pub struct CFRunLoop(CFRunLoopRef); - -impl Drop for CFRunLoop { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - -impl_TCFType!(CFRunLoop, CFRunLoopRef, CFRunLoopGetTypeID); - -impl CFRunLoop { - pub fn get_current() -> CFRunLoop { - unsafe { - let run_loop_ref = CFRunLoopGetCurrent(); - TCFType::wrap_under_get_rule(run_loop_ref) - } - } - - pub fn get_main() -> CFRunLoop { - unsafe { - let run_loop_ref = CFRunLoopGetMain(); - TCFType::wrap_under_get_rule(run_loop_ref) - } - } - - pub fn run_current() { - unsafe { - CFRunLoopRun(); - } - } - - pub fn stop(&self) { - unsafe { - CFRunLoopStop(self.0); - } - } - - pub fn current_mode(&self) -> Option { - unsafe { - let string_ref = CFRunLoopCopyCurrentMode(self.0); - if string_ref.is_null() { - return None; - } - - let cf_string: CFString = TCFType::wrap_under_create_rule(string_ref); - Some(cf_string.to_string()) - } - } - - pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) -> bool { - unsafe { - CFRunLoopContainsTimer(self.0, timer.0, mode) != 0 - } - } - - pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) { - unsafe { - CFRunLoopAddTimer(self.0, timer.0, mode); - } - } - -} - -#[repr(C)] -struct __CFRunLoop; - -pub type CFRunLoopRef = *const __CFRunLoop; - -#[repr(C)] -struct __CFRunLoopSource; - -pub type CFRunLoopSourceRef = *const __CFRunLoopSource; - -#[repr(C)] -struct __CFRunLoopObserver; - -pub type CFRunLoopObserverRef = *const __CFRunLoopObserver; - -// Reasons for CFRunLoopRunInMode() to Return -pub const kCFRunLoopRunFinished: i32 = 1; -pub const kCFRunLoopRunStopped: i32 = 2; -pub const kCFRunLoopRunTimedOut: i32 = 3; -pub const kCFRunLoopRunHandledSource: i32 = 4; - -// Run Loop Observer Activities -//typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { -pub type CFRunLoopActivity = CFOptionFlags; -pub const kCFRunLoopEntry: CFOptionFlags = 1 << 0; -pub const kCFRunLoopBeforeTimers: CFOptionFlags = 1 << 1; -pub const kCFRunLoopBeforeSources: CFOptionFlags = 1 << 2; -pub const kCFRunLoopBeforeWaiting: CFOptionFlags = 1 << 5; -pub const kCFRunLoopAfterWaiting: CFOptionFlags = 1 << 6; -pub const kCFRunLoopExit: CFOptionFlags = 1 << 7; -pub const kCFRunLoopAllActivities: CFOptionFlags = 0x0FFFFFFF; - -#[repr(C)] -pub struct CFRunLoopSourceContext { - version: CFIndex, - info: *mut c_void, - retain: extern "C" fn (info: *const c_void) -> *const c_void, - release: extern "C" fn (info: *const c_void), - copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, - equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, - hash: extern "C" fn (info: *const c_void) -> CFHashCode, - schedule: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), - cancel: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), - perform: extern "C" fn (info: *const c_void), -} - -#[repr(C)] -pub struct CFRunLoopSourceContext1 { - version: CFIndex, - info: *mut c_void, - retain: extern "C" fn (info: *const c_void) -> *const c_void, - release: extern "C" fn (info: *const c_void), - copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, - equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, - hash: extern "C" fn (info: *const c_void) -> CFHashCode, - // note that the following two fields are platform dependent in the C header, the ones here are for OS X - getPort: extern "C" fn (info: *mut c_void) -> mach_port_t, - perform: extern "C" fn (msg: *mut c_void, size: CFIndex, allocator: CFAllocatorRef, info: *mut c_void) -> *mut c_void, -} - -#[repr(C)] -pub struct CFRunLoopObserverContext { - version: CFIndex, - info: *mut c_void, - retain: extern "C" fn (info: *const c_void) -> *const c_void, - release: extern "C" fn (info: *const c_void), - copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, -} - -pub type CFRunLoopObserverCallBack = extern "C" fn (observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); - -#[repr(C)] -pub struct CFRunLoopTimerContext { - version: CFIndex, - info: *mut c_void, - retain: extern "C" fn (info: *const c_void) -> *const c_void, - release: extern "C" fn (info: *const c_void), - copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, -} - -pub type CFRunLoopTimerCallBack = extern "C" fn (timer: CFRunLoopTimerRef, info: *mut c_void); - -#[repr(C)] -struct __CFRunLoopTimer; - -pub type CFRunLoopTimerRef = *const __CFRunLoopTimer; - -pub struct CFRunLoopTimer(CFRunLoopTimerRef); - -impl Drop for CFRunLoopTimer { - fn drop(&mut self) { - unsafe { - CFRelease(self.as_CFTypeRef()) - } - } -} - -impl_TCFType!(CFRunLoopTimer, CFRunLoopTimerRef, CFRunLoopTimerGetTypeID); - -impl CFRunLoopTimer { - pub fn new(fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimer { - unsafe { - let timer_ref = CFRunLoopTimerCreate(kCFAllocatorDefault, fireDate, interval, flags, order, callout, context); - TCFType::wrap_under_create_rule(timer_ref) - } - } -} - - -#[allow(dead_code)] -#[link(name = "CoreFoundation", kind = "framework")] -extern { - /* - * CFRunLoop.h - */ - pub static kCFRunLoopDefaultMode: CFStringRef; - pub static kCFRunLoopCommonModes: CFStringRef; - fn CFRunLoopGetTypeID() -> CFTypeID; - fn CFRunLoopGetCurrent() -> CFRunLoopRef; - fn CFRunLoopGetMain() -> CFRunLoopRef; - fn CFRunLoopCopyCurrentMode(rl: CFRunLoopRef) -> CFStringRef; - fn CFRunLoopCopyAllModes(rl: CFRunLoopRef) -> CFArrayRef; - fn CFRunLoopAddCommonMode(rl: CFRunLoopRef, mode: CFStringRef); - fn CFRunLoopGetNextTimerFireDate(rl: CFRunLoopRef, mode: CFStringRef) -> CFAbsoluteTime; - fn CFRunLoopRun(); - fn CFRunLoopRunInMode(mode: CFStringRef, seconds: CFTimeInterval, returnAfterSourceHandled: Boolean) -> i32; - fn CFRunLoopIsWaiting(rl: CFRunLoopRef) -> Boolean; - fn CFRunLoopWakeUp(rl: CFRunLoopRef); - fn CFRunLoopStop(rl: CFRunLoopRef); - // fn CFRunLoopPerformBlock(rl: CFRunLoopRef, mode: CFTypeRef, block: void (^)(void)); - fn CFRunLoopContainsSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef) -> Boolean; - fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); - fn CFRunLoopRemoveSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); - fn CFRunLoopContainsObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef) -> Boolean; - fn CFRunLoopAddObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); - fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); - fn CFRunLoopContainsTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef) -> Boolean; - fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); - fn CFRunLoopRemoveTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); - - fn CFRunLoopSourceGetTypeID() -> CFTypeID; - fn CFRunLoopSourceCreate(allocator: CFAllocatorRef, order: CFIndex, context: *mut CFRunLoopSourceContext) -> CFRunLoopSourceRef; - fn CFRunLoopSourceGetOrder(source: CFRunLoopSourceRef) -> CFIndex; - fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); - fn CFRunLoopSourceIsValid(source: CFRunLoopSourceRef) -> Boolean; - fn CFRunLoopSourceGetContext(source: CFRunLoopSourceRef, context: *mut CFRunLoopSourceContext); - fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); - - fn CFRunLoopObserverGetTypeID() -> CFTypeID; - fn CFRunLoopObserverCreate(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, callout: CFRunLoopObserverCallBack, context: *mut CFRunLoopObserverContext) -> CFRunLoopObserverRef; - // fn CFRunLoopObserverCreateWithHandler(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, block: void (^) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) -> CFRunLoopObserverRef; - fn CFRunLoopObserverGetActivities(observer: CFRunLoopObserverRef) -> CFOptionFlags; - fn CFRunLoopObserverDoesRepeat(observer: CFRunLoopObserverRef) -> Boolean; - fn CFRunLoopObserverGetOrder(observer: CFRunLoopObserverRef) -> CFIndex; - fn CFRunLoopObserverInvalidate(observer: CFRunLoopObserverRef); - fn CFRunLoopObserverIsValid(observer: CFRunLoopObserverRef) -> Boolean; - fn CFRunLoopObserverGetContext(observer: CFRunLoopObserverRef, context: *mut CFRunLoopObserverContext); - - fn CFRunLoopTimerGetTypeID() -> CFTypeID; - fn CFRunLoopTimerCreate(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimerRef; - // fn CFRunLoopTimerCreateWithHandler(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, block: void (^) (CFRunLoopTimerRef timer)) -> CFRunLoopTimerRef; - fn CFRunLoopTimerGetNextFireDate(timer: CFRunLoopTimerRef) -> CFAbsoluteTime; - fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); - fn CFRunLoopTimerGetInterval(timer: CFRunLoopTimerRef) -> CFTimeInterval; - fn CFRunLoopTimerDoesRepeat(timer: CFRunLoopTimerRef) -> Boolean; - fn CFRunLoopTimerGetOrder(timer: CFRunLoopTimerRef) -> CFIndex; - fn CFRunLoopTimerInvalidate(timer: CFRunLoopTimerRef); - fn CFRunLoopTimerIsValid(timer: CFRunLoopTimerRef) -> Boolean; - fn CFRunLoopTimerGetContext(timer: CFRunLoopTimerRef, context: *mut CFRunLoopTimerContext); - fn CFRunLoopTimerGetTolerance(timer: CFRunLoopTimerRef) -> CFTimeInterval; - fn CFRunLoopTimerSetTolerance(timer: CFRunLoopTimerRef, tolerance: CFTimeInterval); -} - -#[cfg(test)] -mod test { - use super::*; - use date::{CFAbsoluteTime, CFAbsoluteTimeGetCurrent}; - use std::mem; - use libc::c_void; - - #[test] - fn wait_200_milliseconds() { - let run_loop = CFRunLoop::get_current(); - let mut now = unsafe { CFAbsoluteTimeGetCurrent() }; - let mut context = unsafe { CFRunLoopTimerContext { - version: 0, - info: mem::transmute(&mut now), - retain: mem::zeroed(), - release: mem::zeroed(), - copyDescription: mem::zeroed(), - } }; - - - let run_loop_timer = CFRunLoopTimer::new(now + 0.20f64, 0f64, 0, 0, timer_popped, &mut context); - run_loop.add_timer(&run_loop_timer, kCFRunLoopDefaultMode); - - CFRunLoop::run_current(); - } - - extern "C" fn timer_popped(_timer: CFRunLoopTimerRef, _info: *mut c_void) { - let previous_now_ptr: *const CFAbsoluteTime = unsafe { mem::transmute(_info) }; - let previous_now = unsafe { *previous_now_ptr }; - let now = unsafe { CFAbsoluteTimeGetCurrent() }; - assert!(now - previous_now > 0.19 && now - previous_now < 0.21); - CFRunLoop::get_current().stop(); - } -}