From f80172e0762717d8520a367026f6c0312bec23b6 Mon Sep 17 00:00:00 2001
From: Joe Groff <arcata@gmail.com>
Date: Sun, 13 Jul 2008 19:19:16 -0700
Subject: [PATCH] replace limited assoc>NSDictionary word with a >plist word
 that can convert any structure of numbers, strings, byte-arrays, hashtables,
 and sequences into the equivalent Cocoa objects

---
 extra/cocoa/application/application.factor   | 12 ++++-
 extra/cocoa/plists/plists.factor             | 25 ++++++----
 extra/core-foundation/core-foundation.factor | 50 +++++++++++++++++++-
 3 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/extra/cocoa/application/application.factor b/extra/cocoa/application/application.factor
index 3e6f8c5be7..a28952ea33 100755
--- a/extra/cocoa/application/application.factor
+++ b/extra/cocoa/application/application.factor
@@ -3,12 +3,20 @@
 USING: alien alien.syntax io kernel namespaces core-foundation
 core-foundation.run-loop cocoa.messages cocoa cocoa.classes
 cocoa.runtime sequences threads debugger init summary
-kernel.private ;
+kernel.private assocs ;
 IN: cocoa.application
 
 : <NSString> ( str -- alien ) <CFString> -> autorelease ;
-
 : <NSArray> ( seq -- alien ) <CFArray> -> autorelease ;
+: <NSNumber> ( number -- alien ) <CFNumber> -> autorelease ;
+: <NSData> ( byte-array -- alien ) <CFData> -> autorelease ;
+: <NSDictionary> ( assoc -- alien )
+    NSMutableDictionary over assoc-size -> dictionaryWithCapacity:
+    [
+        [
+            spin -> setObject:forKey:
+        ] curry assoc-each
+    ] keep ;
 
 : NSApplicationDelegateReplySuccess 0 ;
 : NSApplicationDelegateReplyCancel  1 ;
diff --git a/extra/cocoa/plists/plists.factor b/extra/cocoa/plists/plists.factor
index 4ffc1db139..139e0840e1 100644
--- a/extra/cocoa/plists/plists.factor
+++ b/extra/cocoa/plists/plists.factor
@@ -6,16 +6,25 @@ namespaces io.backend math cocoa.enumeration byte-arrays
 combinators alien.c-types ;
 IN: cocoa.plists
 
-: assoc>NSDictionary ( assoc -- alien )
-    NSMutableDictionary over assoc-size -> dictionaryWithCapacity:
-    [
-        [
-            spin [ <NSString> ] bi@ -> setObject:forKey:
-        ] curry assoc-each
-    ] keep ;
+GENERIC: >plist ( value -- plist )
+
+M: number >plist
+    <NSNumber> ;
+M: t >plist
+    <NSNumber> ;
+M: f >plist
+    <NSNumber> ;
+M: string >plist
+    <NSString> ;
+M: byte-array >plist
+    <NSData> ;
+M: hashtable >plist
+    [ [ >plist ] bi@ ] assoc-map <NSDictionary> ;
+M: sequence >plist
+    [ >plist ] map <NSArray> ;
 
 : write-plist ( assoc path -- )
-    >r assoc>NSDictionary
+    >r >plist
     r> normalize-path <NSString> 0 -> writeToFile:atomically:
     [ "write-plist failed" throw ] unless ;
 
diff --git a/extra/core-foundation/core-foundation.factor b/extra/core-foundation/core-foundation.factor
index b91493d2be..e1c2c4c517 100644
--- a/extra/core-foundation/core-foundation.factor
+++ b/extra/core-foundation/core-foundation.factor
@@ -6,16 +6,44 @@ IN: core-foundation
 
 TYPEDEF: void* CFAllocatorRef
 TYPEDEF: void* CFArrayRef
+TYPEDEF: void* CFDataRef
+TYPEDEF: void* CFDictionaryRef
+TYPEDEF: void* CFMutableDictionaryRef
+TYPEDEF: void* CFNumberRef
 TYPEDEF: void* CFBundleRef
+TYPEDEF: void* CFRunLoopRef
+TYPEDEF: void* CFSetRef
 TYPEDEF: void* CFStringRef
 TYPEDEF: void* CFURLRef
 TYPEDEF: void* CFUUIDRef
+TYPEDEF: void* CFTypeRef
 TYPEDEF: bool Boolean
 TYPEDEF: int CFIndex
 TYPEDEF: int SInt32
+TYPEDEF: uint UInt32
+TYPEDEF: uint CFTypeID
 TYPEDEF: double CFTimeInterval
 TYPEDEF: double CFAbsoluteTime
 
+TYPEDEF: int CFNumberType
+: kCFNumberSInt8Type 1 ; inline
+: kCFNumberSInt16Type 2 ; inline
+: kCFNumberSInt32Type 3 ; inline
+: kCFNumberSInt64Type 4 ; inline
+: kCFNumberFloat32Type 5 ; inline
+: kCFNumberFloat64Type 6 ; inline
+: kCFNumberCharType 7 ; inline
+: kCFNumberShortType 8 ; inline
+: kCFNumberIntType 9 ; inline
+: kCFNumberLongType 10 ; inline
+: kCFNumberLongLongType 11 ; inline
+: kCFNumberFloatType 12 ; inline
+: kCFNumberDoubleType 13 ; inline
+: kCFNumberCFIndexType 14 ; inline
+: kCFNumberNSIntegerType 15 ; inline
+: kCFNumberCGFloatType 16 ; inline
+: kCFNumberMaxType 16 ; inline
+
 FUNCTION: CFArrayRef CFArrayCreateMutable ( CFAllocatorRef allocator, CFIndex capacity, void* callbacks ) ;
 
 FUNCTION: void* CFArrayGetValueAtIndex ( CFArrayRef array, CFIndex idx ) ;
@@ -39,11 +67,18 @@ FUNCTION: CFIndex CFStringGetLength ( CFStringRef theString ) ;
 
 FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex length, void* buffer ) ;
 
+FUNCTION: CFNumberRef CFNumberCreate ( CFAllocatorRef allocator, CFNumberType theType, void* valuePtr ) ;
+
+FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, uchar* bytes, CFIndex length ) ;
+
 FUNCTION: CFBundleRef CFBundleCreate ( CFAllocatorRef allocator, CFURLRef bundleURL ) ;
 
 FUNCTION: Boolean CFBundleLoadExecutable ( CFBundleRef bundle ) ;
 
-FUNCTION: void CFRelease ( void* cf ) ;
+FUNCTION: CFTypeRef CFRetain ( CFTypeRef cf ) ;
+FUNCTION: void CFRelease ( CFTypeRef cf ) ;
+
+FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ;
 
 : CF>array ( alien -- array )
     dup CFArrayGetCount [ CFArrayGetValueAtIndex ] with map ;
@@ -81,6 +116,19 @@ FUNCTION: void CFRelease ( void* cf ) ;
         f swap CFBundleCreate
     ] keep CFRelease ;
 
+GENERIC: <CFNumber> ( number -- alien )
+M: integer <CFNumber>
+    [ f kCFNumberLongLongType ] dip <longlong> CFNumberCreate ;
+M: float <CFNumber>
+    [ f kCFNumberDoubleType ] dip <double> CFNumberCreate ;
+M: t <CFNumber>
+    drop f kCFNumberIntType 1 <int> CFNumberCreate ;
+M: f <CFNumber>
+    drop f kCFNumberIntType 0 <int> CFNumberCreate ;
+
+: <CFData> ( byte-array -- alien )
+    [ f ] dip dup length CFDataCreate ;
+
 : load-framework ( name -- )
     dup <CFBundle> [
         CFBundleLoadExecutable drop