Updating ITFoundation to include updates spurred by Haven development.
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Fri, 19 Sep 2008 11:56:14 +0000 (11:56 +0000)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Fri, 19 Sep 2008 11:56:14 +0000 (11:56 +0000)
ITUUID function for easy generation of new UUIDs,
ITThreadChild and ITThreadParent protocols for threading based on Subjugator implementation,
ITSharedController for simple implementation of a controller that maintains a shared instance (used by ITApplicationController in ITKit),
ITSQLite3Database wraps the sqlite3 C API nicely, though more work could be done,
ITDebug adds more functions for logging,
ITCategory-NSString adds MD5 and SHA1 hashing, around the new ITCategory-NSData methods,
and ITCategory-NSData adds MD5 and SHA1 hashing, and a hexadecimalRepresentation method that goes well with the hashes.

16 files changed:
ITCategory-NSData.h [new file with mode: 0644]
ITCategory-NSData.m [new file with mode: 0644]
ITCategory-NSString.h
ITCategory-NSString.m
ITDebug.h
ITDebug.m
ITFoundation.h
ITFoundation.xcodeproj/project.pbxproj
ITSQLite3Database.h [new file with mode: 0644]
ITSQLite3Database.m [new file with mode: 0644]
ITSharedController.h [new file with mode: 0644]
ITSharedController.m [new file with mode: 0644]
ITThreadChild.h [new file with mode: 0644]
ITThreadChild.m [new file with mode: 0644]
ITUUID.h [new file with mode: 0644]
ITUUID.m [new file with mode: 0644]

diff --git a/ITCategory-NSData.h b/ITCategory-NSData.h
new file mode 100644 (file)
index 0000000..68af6e3
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *     ITFoundation
+ *     ITCategory-NSData.h
+ *
+ *     Copyright (c) 2008 by iThink Software.
+ *     All Rights Reserved.
+ *
+ *     $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface NSData (ITFoundationCategory)
+
+- (NSString *)hexadecimalRepresentation;
+
+- (NSData *)MD5;
+- (NSData *)SHA1;
+
+@end
diff --git a/ITCategory-NSData.m b/ITCategory-NSData.m
new file mode 100644 (file)
index 0000000..0f45f68
--- /dev/null
@@ -0,0 +1,36 @@
+#import "ITCategory-NSData.h"
+#import <openssl/md5.h>
+#import <openssl/sha.h>
+
+@implementation NSData (ITFoundationCategory)
+
+- (NSString *)hexadecimalRepresentation {
+       int dataLength = [self length];
+       int stringLength = dataLength * 2;
+       
+       char *dataBytes = [self bytes];
+       char hexString[stringLength];
+       
+       int i;
+       for (i=0; i < dataLength; i++) {
+               sprintf(hexString + (i * 2), "%02x", dataBytes[i]);
+       }
+       
+       return [NSString stringWithCString:hexString length:stringLength];
+}
+
+- (NSData *)MD5 {
+       int length = 16;
+       unsigned char digest[length];
+       MD5([self bytes], [self length], digest);
+       return [NSData dataWithBytes:&digest length:length];
+}
+
+- (NSData *)SHA1 {
+       int length = 20;
+       unsigned char digest[length];
+       SHA1([self bytes], [self length], digest);
+       return [NSData dataWithBytes:&digest length:length];
+}
+
+@end
index a0429f0..37a8572 100644 (file)
@@ -18,4 +18,7 @@
 - (id)initWithFourCharCode:(unsigned long)fourCharCode;
 - (unsigned long)fourCharCode;
 
+- (NSData *)MD5;
+- (NSData *)SHA1;
+
 @end
\ No newline at end of file
index e08e046..6aed778 100644 (file)
@@ -1,4 +1,5 @@
 #import "ITCategory-NSString.h"
+#import "ITCategory-NSData.h"
 
 @implementation NSString (ITFoundationCategory)
 
@@ -7,7 +8,7 @@
 }
 
 - (id)initWithFourCharCode:(unsigned long)fourCharCode {
-       return UTCreateStringForOSType(fourCharCode);
+       return [self initWithString:(NSString *)UTCreateStringForOSType(fourCharCode)];
        //return [self initWithFormat:@"%.4s", &fourCharCode];
 }
 
        return tmp |= *c_s++;*/
 }
 
+- (NSData *)MD5 {
+       return [[self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO] MD5];
+}
+
+- (NSData *)SHA1 {
+       return [[self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO] SHA1];
+}
+
 @end
\ No newline at end of file
index eaf6483..c53ae69 100644 (file)
--- a/ITDebug.h
+++ b/ITDebug.h
@@ -4,7 +4,7 @@
  *
  *     Functions for logging debugging information intelligently.
  *
- *     Copyright (c) 2005 by iThink Software.
+ *     Copyright (c) 2008 by iThink Software.
  *     All Rights Reserved.
  *
  *     $Id$
@@ -13,5 +13,7 @@
 
 #import <Foundation/Foundation.h>
 
+extern NSString *ITDebugErrorPrefixForObject(id object);
+extern BOOL ITDebugMode();
 extern void SetITDebugMode(BOOL mode);
 extern void ITDebugLog(NSString *format, ...);
\ No newline at end of file
index a5666aa..578853c 100644 (file)
--- a/ITDebug.m
+++ b/ITDebug.m
@@ -1,7 +1,15 @@
 #import "ITDebug.h"
 
+NSString *ITDebugErrorPrefixForObject(id object) {
+       return [NSString stringWithFormat:@"[ERROR] %@(0x%x):", NSStringFromClass([object class]), object];
+}
+
 static BOOL _ITDebugMode = NO;
 
+BOOL ITDebugMode() {
+       return _ITDebugMode;
+}
+
 void SetITDebugMode(BOOL mode) {
        _ITDebugMode = mode;
 }
index d7f63ab..377efcb 100644 (file)
@@ -4,7 +4,7 @@
  *
  *     iThink Software's custom extensions to Apple's Foundation framework.
  *
- *     Copyright (c) 2005 by iThink Software.
+ *     Copyright (c) 2008 by iThink Software.
  *     All Rights Reserved.
  *
  *     $Id$
 #import <ITFoundation/ITByteStream.h>
 #import <ITFoundation/ITCarbonSupport.h>
 #import <ITFoundation/ITDebug.h>
+#import <ITFoundation/ITSharedController.h>
+#import <ITFoundation/ITSQLite3Database.h>
+#import <ITFoundation/ITThreadChild.h>
+#import <ITFoundation/ITUUID.h>
 
+#import <ITFoundation/ITCategory-NSBundle.h>
+#import <ITFoundation/ITCategory-NSData.h>
 #import <ITFoundation/ITCategory-NSObject.h>
 #import <ITFoundation/ITCategory-NSProxy.h>
 #import <ITFoundation/ITCategory-NSString.h>
-#import <ITFoundation/ITCategory-NSBundle.h>
\ No newline at end of file
index c09ff97..3e9b6bd 100644 (file)
                7CB02EB707D049BB00959EA0 /* ITCategory-NSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CB02EB507D049BB00959EA0 /* ITCategory-NSProxy.m */; };
                8DC2EF510486A6940098B216 /* ITFoundation_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCF5E0370ADEE00C91783 /* ITFoundation_Prefix.pch */; };
                8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
+               FABDFA540E7BBFA200BEDC10 /* ITUUID.h in Headers */ = {isa = PBXBuildFile; fileRef = FABDFA520E7BBFA200BEDC10 /* ITUUID.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               FABDFA550E7BBFA200BEDC10 /* ITUUID.m in Sources */ = {isa = PBXBuildFile; fileRef = FABDFA530E7BBFA200BEDC10 /* ITUUID.m */; };
+               FAC0E6F20E7B61DD00698C8A /* ITSharedController.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC0E6F00E7B61DD00698C8A /* ITSharedController.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               FAC0E6F30E7B61DD00698C8A /* ITSharedController.m in Sources */ = {isa = PBXBuildFile; fileRef = FAC0E6F10E7B61DD00698C8A /* ITSharedController.m */; };
+               FAC0E6FE0E7B66A400698C8A /* ITThreadChild.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC0E6FC0E7B66A400698C8A /* ITThreadChild.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               FAC0E6FF0E7B66A400698C8A /* ITThreadChild.m in Sources */ = {isa = PBXBuildFile; fileRef = FAC0E6FD0E7B66A400698C8A /* ITThreadChild.m */; };
+               FAC0E7D60E7B6F6900698C8A /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC0E7D50E7B6F6900698C8A /* libsqlite3.dylib */; };
+               FAC0E7DB0E7B6F9D00698C8A /* ITSQLite3Database.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC0E7D90E7B6F9D00698C8A /* ITSQLite3Database.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               FAC0E7DC0E7B6F9D00698C8A /* ITSQLite3Database.m in Sources */ = {isa = PBXBuildFile; fileRef = FAC0E7DA0E7B6F9D00698C8A /* ITSQLite3Database.m */; };
+               FAD9BF020E83BF7400E110AF /* ITCategory-NSData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD9BF000E83BF7400E110AF /* ITCategory-NSData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+               FAD9BF030E83BF7400E110AF /* ITCategory-NSData.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD9BF010E83BF7400E110AF /* ITCategory-NSData.m */; };
+               FAD9BF0D0E83C29D00E110AF /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD9BF0C0E83C29D00E110AF /* libcrypto.dylib */; };
 /* End PBXBuildFile section */
 
-/* Begin PBXBuildStyle section */
-               014CEA440018CDF011CA2923 /* Development */ = {
-                       isa = PBXBuildStyle;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 0;
-                               ZERO_LINK = YES;
-                       };
-                       name = Development;
-               };
-               014CEA450018CDF011CA2923 /* Deployment */ = {
-                       isa = PBXBuildStyle;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               ZERO_LINK = NO;
-                       };
-                       name = Deployment;
-               };
-/* End PBXBuildStyle section */
-
 /* Begin PBXFileReference section */
                0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
                089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
                7CB02EB507D049BB00959EA0 /* ITCategory-NSProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSProxy.m"; sourceTree = "<group>"; };
                8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
                8DC2EF5B0486A6940098B216 /* ITFoundation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ITFoundation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+               FABDFA520E7BBFA200BEDC10 /* ITUUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITUUID.h; sourceTree = "<group>"; };
+               FABDFA530E7BBFA200BEDC10 /* ITUUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITUUID.m; sourceTree = "<group>"; };
+               FAC0E6F00E7B61DD00698C8A /* ITSharedController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITSharedController.h; sourceTree = "<group>"; };
+               FAC0E6F10E7B61DD00698C8A /* ITSharedController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITSharedController.m; sourceTree = "<group>"; };
+               FAC0E6FC0E7B66A400698C8A /* ITThreadChild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITThreadChild.h; sourceTree = "<group>"; };
+               FAC0E6FD0E7B66A400698C8A /* ITThreadChild.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITThreadChild.m; sourceTree = "<group>"; };
+               FAC0E7D50E7B6F6900698C8A /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = "<absolute>"; };
+               FAC0E7D90E7B6F9D00698C8A /* ITSQLite3Database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITSQLite3Database.h; sourceTree = "<group>"; };
+               FAC0E7DA0E7B6F9D00698C8A /* ITSQLite3Database.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITSQLite3Database.m; sourceTree = "<group>"; };
+               FAD9BF000E83BF7400E110AF /* ITCategory-NSData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ITCategory-NSData.h"; sourceTree = "<group>"; };
+               FAD9BF010E83BF7400E110AF /* ITCategory-NSData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSData.m"; sourceTree = "<group>"; };
+               FAD9BF0C0E83C29D00E110AF /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = /usr/lib/libcrypto.dylib; sourceTree = "<absolute>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -91,6 +91,8 @@
                        files = (
                                7C56C0C907D5D2450099829E /* Foundation.framework in Frameworks */,
                                3769DF0109A01F9000573A04 /* ApplicationServices.framework in Frameworks */,
+                               FAC0E7D60E7B6F6900698C8A /* libsqlite3.dylib in Frameworks */,
+                               FAD9BF0D0E83C29D00E110AF /* libcrypto.dylib in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
                        isa = PBXGroup;
                        children = (
+                               FAD9BF0C0E83C29D00E110AF /* libcrypto.dylib */,
+                               FAC0E7D50E7B6F6900698C8A /* libsqlite3.dylib */,
                                3769DF0009A01F9000573A04 /* ApplicationServices.framework */,
                                0867D69BFE84028FC02AAC07 /* Foundation.framework */,
                        );
                08FB77AEFE84172EC02AAC07 /* Classes */ = {
                        isa = PBXGroup;
                        children = (
-                               37B1C5280612596900F99008 /* ITByteStream */,
-                               37B1C51F0612594A00F99008 /* ITCarbonSupport */,
-                               37B1C5190612593A00F99008 /* ITDebug */,
-                               37B1C5250612596000F99008 /* ITVMInfo */,
-                               37B1C52B0612597100F99008 /* ITXML */,
+                               7CA50B8C054E787D0074E1D9 /* ITByteStream.h */,
+                               7CA50B8B054E787D0074E1D9 /* ITByteStream.m */,
+                               7C97DC2C05B614300013E85F /* ITCarbonSupport.h */,
+                               7C97DC2D05B614300013E85F /* ITCarbonSupport.m */,
+                               7CA50B2F054E77A00074E1D9 /* ITDebug.h */,
+                               7CA50B30054E77A00074E1D9 /* ITDebug.m */,
+                               FAC0E7D90E7B6F9D00698C8A /* ITSQLite3Database.h */,
+                               FAC0E7DA0E7B6F9D00698C8A /* ITSQLite3Database.m */,
+                               FAC0E6F00E7B61DD00698C8A /* ITSharedController.h */,
+                               FAC0E6F10E7B61DD00698C8A /* ITSharedController.m */,
+                               FAC0E6FC0E7B66A400698C8A /* ITThreadChild.h */,
+                               FAC0E6FD0E7B66A400698C8A /* ITThreadChild.m */,
+                               FABDFA520E7BBFA200BEDC10 /* ITUUID.h */,
+                               FABDFA530E7BBFA200BEDC10 /* ITUUID.m */,
+                               37B1C52B0612597100F99008 /* Incomplete and Deprecated */,
                        );
                        name = Classes;
                        sourceTree = "<group>";
                                7C0462080801DC3700433407 /* ITCategory-NSString.m */,
                                7C2D93BD07C2FD6700A487A9 /* ITCategory-NSBundle.h */,
                                7C2D93BE07C2FD6700A487A9 /* ITCategory-NSBundle.m */,
+                               FAD9BF000E83BF7400E110AF /* ITCategory-NSData.h */,
+                               FAD9BF010E83BF7400E110AF /* ITCategory-NSData.m */,
                        );
                        name = Categories;
                        sourceTree = "<group>";
                        name = "Other Sources";
                        sourceTree = "<group>";
                };
-               37B1C5190612593A00F99008 /* ITDebug */ = {
-                       isa = PBXGroup;
-                       children = (
-                               7CA50B2F054E77A00074E1D9 /* ITDebug.h */,
-                               7CA50B30054E77A00074E1D9 /* ITDebug.m */,
-                       );
-                       name = ITDebug;
-                       sourceTree = "<group>";
-               };
-               37B1C51F0612594A00F99008 /* ITCarbonSupport */ = {
-                       isa = PBXGroup;
-                       children = (
-                               7C97DC2C05B614300013E85F /* ITCarbonSupport.h */,
-                               7C97DC2D05B614300013E85F /* ITCarbonSupport.m */,
-                       );
-                       name = ITCarbonSupport;
-                       sourceTree = "<group>";
-               };
-               37B1C5250612596000F99008 /* ITVMInfo */ = {
+               37B1C52B0612597100F99008 /* Incomplete and Deprecated */ = {
                        isa = PBXGroup;
                        children = (
                                7CA50B80054E786E0074E1D9 /* ITVirtualMemoryInfo.h */,
                                7CA50B7F054E786E0074E1D9 /* ITVirtualMemoryInfo.m */,
-                       );
-                       name = ITVMInfo;
-                       sourceTree = "<group>";
-               };
-               37B1C5280612596900F99008 /* ITByteStream */ = {
-                       isa = PBXGroup;
-                       children = (
-                               7CA50B8C054E787D0074E1D9 /* ITByteStream.h */,
-                               7CA50B8B054E787D0074E1D9 /* ITByteStream.m */,
-                       );
-                       name = ITByteStream;
-                       sourceTree = "<group>";
-               };
-               37B1C52B0612597100F99008 /* ITXML */ = {
-                       isa = PBXGroup;
-                       children = (
                                37B1C5740612599000F99008 /* ITXMLParser.h */,
                                37B1C5750612599000F99008 /* ITXMLParser.m */,
                                37B1C5760612599000F99008 /* ITXMLNode.h */,
                                37B1C5730612599000F99008 /* ITXMLNode.m */,
                        );
-                       name = ITXML;
+                       name = "Incomplete and Deprecated";
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
                                7C2D93BF07C2FD6700A487A9 /* ITCategory-NSBundle.h in Headers */,
                                7CB02EB607D049BB00959EA0 /* ITCategory-NSProxy.h in Headers */,
                                7C0462090801DC3700433407 /* ITCategory-NSString.h in Headers */,
+                               FAC0E6F20E7B61DD00698C8A /* ITSharedController.h in Headers */,
+                               FAC0E6FE0E7B66A400698C8A /* ITThreadChild.h in Headers */,
+                               FAC0E7DB0E7B6F9D00698C8A /* ITSQLite3Database.h in Headers */,
+                               FABDFA540E7BBFA200BEDC10 /* ITUUID.h in Headers */,
+                               FAD9BF020E83BF7400E110AF /* ITCategory-NSData.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        buildRules = (
                        );
-                       buildSettings = {
-                               DYLIB_COMPATIBILITY_VERSION = 1;
-                               DYLIB_CURRENT_VERSION = 1;
-                               FRAMEWORK_VERSION = A;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               GCC_PREFIX_HEADER = ITFoundation_Prefix.pch;
-                               INFOPLIST_FILE = Info.plist;
-                               INSTALL_PATH = "@executable_path/../Frameworks";
-                               LIBRARY_STYLE = DYNAMIC;
-                               MACOSX_DEPLOYMENT_TARGET = 10.2;
-                               OTHER_LDFLAGS = (
-                                       "-seg1addr",
-                                       0x15000000,
-                               );
-                               PRODUCT_NAME = ITFoundation;
-                               WRAPPER_EXTENSION = framework;
-                       };
                        dependencies = (
                        );
                        name = ITFoundation;
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 7CC441C208A83AFA001BCF9B /* Build configuration list for PBXProject "ITFoundation" */;
-                       buildSettings = {
-                               MACOSX_DEPLOYMENT_TARGET = 10.2;
-                               SDKROOT = /Developer/SDKs/MacOSX10.2.8.sdk;
-                       };
-                       buildStyles = (
-                               014CEA440018CDF011CA2923 /* Development */,
-                               014CEA450018CDF011CA2923 /* Deployment */,
-                       );
+                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 0867D691FE84028FC02AAC07 /* ITFoundation */;
                        productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
                        projectDirPath = "";
+                       projectRoot = "";
                        targets = (
                                8DC2EF4F0486A6940098B216 /* ITFoundation */,
                        );
                                7C2D93C007C2FD6700A487A9 /* ITCategory-NSBundle.m in Sources */,
                                7CB02EB707D049BB00959EA0 /* ITCategory-NSProxy.m in Sources */,
                                7C04620A0801DC3700433407 /* ITCategory-NSString.m in Sources */,
+                               FAC0E6F30E7B61DD00698C8A /* ITSharedController.m in Sources */,
+                               FAC0E6FF0E7B66A400698C8A /* ITThreadChild.m in Sources */,
+                               FAC0E7DC0E7B6F9D00698C8A /* ITSQLite3Database.m in Sources */,
+                               FABDFA550E7BBFA200BEDC10 /* ITUUID.m in Sources */,
+                               FAD9BF030E83BF7400E110AF /* ITCategory-NSData.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
diff --git a/ITSQLite3Database.h b/ITSQLite3Database.h
new file mode 100644 (file)
index 0000000..ed13477
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     ITFoundation
+ *     ITSQLite3Database.h
+ *
+ *     Copyright (c) 2008 by iThink Software.
+ *     All Rights Reserved.
+ *
+ *     $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+#import <sqlite3.h>
+
+static int sqlite3_bind_objc_object(sqlite3_stmt *statement, int index, id object);
+static id sqlite3_column_objc_object(sqlite3_stmt *statement, int columnIndex);
+
+@interface ITSQLite3Database : NSObject {
+       NSString *dbPath;
+       sqlite3 *db;
+}
+
+- (id)initWithPath:(NSString *)path;
+
+- (BOOL)begin;
+- (BOOL)beginTransaction;
+- (BOOL)commit;
+- (BOOL)commitTransaction;
+- (BOOL)rollback;
+- (BOOL)rollbackTransaction;
+
+- (BOOL)executeQuery:(NSString *)query va_args:(va_list)args;
+- (BOOL)executeQuery:(NSString *)query, ...;
+
+- (NSDictionary *)fetchRow:(NSString *)query va_args:(va_list)args;
+- (NSDictionary *)fetchRow:(NSString *)query, ...;
+
+- (NSArray *)fetchTable:(NSString *)query va_args:(va_list)args;
+- (NSArray *)fetchTable:(NSString *)query, ...;
+
+@end
diff --git a/ITSQLite3Database.m b/ITSQLite3Database.m
new file mode 100644 (file)
index 0000000..1984e6d
--- /dev/null
@@ -0,0 +1,215 @@
+#import "ITSQLite3Database.h"
+
+int sqlite3_bind_objc_object(sqlite3_stmt *statement, int index, id object) {
+       int retval;
+       
+       if ([object isKindOfClass:[NSData class]]) {
+               retval = sqlite3_bind_blob(statement, index, [object bytes], [object length], SQLITE_TRANSIENT);
+       } else if ([object isKindOfClass:[NSDate class]]) {
+               retval = sqlite3_bind_double(statement, index, [object timeIntervalSince1970]);
+       } else if ([object isKindOfClass:[NSNull class]]) {
+               retval = sqlite3_bind_null(statement, index);
+       } else if ([object isKindOfClass:[NSNumber class]]) {
+               if (strcmp([object objCType], @encode(BOOL)) == 0) {
+                       retval = sqlite3_bind_int(statement, index, ([object boolValue] ? 1 : 0));
+               } else if (strcmp([object objCType], @encode(int)) == 0) {
+                       retval = sqlite3_bind_int64(statement, index, [object longValue]);
+               } else if (strcmp([object objCType], @encode(long)) == 0) {
+                       retval = sqlite3_bind_int64(statement, index, [object longValue]);
+               } else if (strcmp([object objCType], @encode(float)) == 0) {
+                       retval = sqlite3_bind_double(statement, index, [object floatValue]);
+               } else if (strcmp([object objCType], @encode(double)) == 0) {
+                       retval = sqlite3_bind_double(statement, index, [object doubleValue]);
+               }
+       }
+       
+       if (!retval) {
+               retval = sqlite3_bind_text(statement, index, [[object description] UTF8String], -1, SQLITE_TRANSIENT);
+       }
+       
+       return retval;
+}
+
+id sqlite3_column_objc_object(sqlite3_stmt *statement, int columnIndex) {
+       id retval;
+       
+       switch (sqlite3_column_type(statement, columnIndex)) {
+               case SQLITE_INTEGER:
+                       retval = [NSNumber numberWithLongLong:sqlite3_column_int64(statement, columnIndex)];
+                       break;
+               case SQLITE_FLOAT:
+                       retval = [NSNumber numberWithDouble:sqlite3_column_double(statement, columnIndex)];
+                       break;
+               case SQLITE_TEXT:
+                       retval = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(statement, columnIndex)];
+                       break;
+               case SQLITE_BLOB:
+                       retval = [NSData dataWithBytes:sqlite3_column_blob(statement, columnIndex) length:sqlite3_column_bytes(statement, columnIndex)];
+                       break;
+               case SQLITE_NULL:
+               default:
+                       retval = [NSNull null];
+                       break;
+       }
+       
+       return retval;
+}
+
+@implementation ITSQLite3Database
+
+- (id)initWithPath:(NSString *)path {
+       if (self = [super init]) {
+               dbPath = [path copy];
+               if (sqlite3_open([dbPath UTF8String], &db) != SQLITE_OK) {
+                       ITDebugLog(@"%@ sqlite3_open(\"%@\"): %@", ITDebugErrorPrefixForObject(self), dbPath, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+                       [self release];
+                       return nil;
+               }
+       }
+       return self;
+}
+
+- (void)dealloc {
+       if (sqlite3_close(db) != SQLITE_OK) {
+               ITDebugLog(@"%@ sqlite3_close(0x%x): %@", ITDebugErrorPrefixForObject(self), db, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+       }
+       [dbPath release];
+       [super dealloc];
+}
+
+- (BOOL)begin {
+       return [self beginTransaction];
+}
+
+- (BOOL)beginTransaction {
+       return [self executeQuery:@"BEGIN TRANSACTION;"];
+}
+
+- (BOOL)commit {
+       return [self commitTransaction];
+}
+
+- (BOOL)commitTransaction {
+       return [self executeQuery:@"COMMIT TRANSACTION;"];
+}
+
+- (BOOL)rollback {
+       return [self rollbackTransaction];
+}
+
+- (BOOL)rollbackTransaction {
+       return [self executeQuery:@"ROLLBACK TRANSACTION;"];
+}
+
+- (BOOL)executeQuery:(NSString *)query va_args:(va_list)args {
+       sqlite3_stmt *statement;
+       
+       if (sqlite3_prepare(db, [query UTF8String], -1, &statement, 0) != SQLITE_OK) {
+               ITDebugLog(@"%@ sqlite3_prepare(0x%x, \"%@\", -1, 0x%x, 0): %@", ITDebugErrorPrefixForObject(self), db, query, statement, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+               return NO;
+       }
+       
+       int argi, argc = sqlite3_bind_parameter_count(statement);
+       for (argi = 0; argi < argc; argi++) {
+               id arg = va_arg(args, id);
+               
+               if (!arg) {
+                       [NSException raise:NSInvalidArgumentException format:@"ITSQLite3Database: -executeQuery expected %i arguments, received %i.", argc, argi];
+                       sqlite3_finalize(statement);
+                       return NO;
+               }
+               
+               sqlite3_bind_objc_object(statement, argi+1, arg);
+       }
+       
+       int stepret = sqlite3_step(statement);
+       int finalizeret = sqlite3_finalize(statement);
+       if (!(stepret == SQLITE_DONE || stepret == SQLITE_ROW)) {
+               ITDebugLog(@"%@ sqlite3_step(0x%x): %@", ITDebugErrorPrefixForObject(self), statement, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+               return NO;
+       }
+       
+       return YES;
+}
+
+- (BOOL)executeQuery:(NSString *)query, ... {
+       va_list args;
+       va_start(args, query);
+       
+       BOOL result = [self executeQuery:query va_args:args];
+       
+       va_end(args);
+       return result;
+}
+
+- (NSDictionary *)fetchRow:(NSString *)query va_args:(va_list)args {
+       NSArray *table = [self fetchTable:query va_args:args];
+       if ([table count] >= 1) {
+               return [table objectAtIndex:0];
+       }
+       return nil;
+}
+
+- (NSDictionary *)fetchRow:(NSString *)query, ... {
+       va_list args;
+       va_start(args, query);
+       
+       id result = [self fetchRow:query va_args:args];
+       
+       va_end(args);
+       return result;
+}
+
+- (NSArray *)fetchTable:(NSString *)query va_args:(va_list)args {
+       sqlite3_stmt *statement;
+       
+       if (sqlite3_prepare(db, [query UTF8String], -1, &statement, 0) != SQLITE_OK) {
+               ITDebugLog(@"%@ sqlite3_prepare(0x%x, \"%@\", -1, 0x%x, 0): %@", ITDebugErrorPrefixForObject(self), db, query, statement, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+               return NO;
+       }
+       
+       int argi, argc = sqlite3_bind_parameter_count(statement);
+       for (argi = 0; argi < argc; argi++) {
+               id arg = va_arg(args, id);
+               
+               if (!arg) {
+                       [NSException raise:NSInvalidArgumentException format:@"ITSQLite3Database: -executeQuery expected %i arguments, received %i.", argc, argi];
+                       sqlite3_finalize(statement);
+                       return NO;
+               }
+               
+               sqlite3_bind_objc_object(statement, argi+1, arg);
+       }
+       
+       NSMutableArray *rowArray = [[NSMutableArray alloc] init];
+       
+       int stepret;
+       while ((stepret = sqlite3_step(statement)) == SQLITE_ROW) {
+               NSMutableDictionary *row = [[NSMutableDictionary alloc] init];
+               int coli, cols = sqlite3_column_count(statement);
+               for (coli = 0; coli < cols; coli++) {
+                       [row setObject:sqlite3_column_objc_object(statement, coli) forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement, coli)]];
+               }
+               [rowArray addObject:[row autorelease]];
+       }
+       
+       int finalizeret = sqlite3_finalize(statement);
+       if (stepret != SQLITE_DONE) {
+               ITDebugLog(@"%@ sqlite3_step(0x%x): %@", ITDebugErrorPrefixForObject(self), statement, [NSString stringWithUTF8String:sqlite3_errmsg(db)]);
+               return NO;
+       }
+       
+       return [rowArray autorelease];
+}
+
+- (NSArray *)fetchTable:(NSString *)query, ... {
+       va_list args;
+       va_start(args, query);
+       
+       id result = [self fetchTable:query va_args:args];
+       
+       va_end(args);
+       return result;
+}
+
+@end
diff --git a/ITSharedController.h b/ITSharedController.h
new file mode 100644 (file)
index 0000000..3b93610
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *     ITFoundation
+ *     ITSharedController.h
+ *
+ *     Copyright (c) 2008 by iThink Software.
+ *     All Rights Reserved.
+ *
+ *     $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface ITSharedController : NSObject {
+
+}
+
++ (id)sharedController;
+
+@end
diff --git a/ITSharedController.m b/ITSharedController.m
new file mode 100644 (file)
index 0000000..1887165
--- /dev/null
@@ -0,0 +1,21 @@
+#import "ITSharedController.h"
+
+static NSMutableDictionary *_ITSharedController_sharedControllers = nil;
+
+@implementation ITSharedController
+
++ (id)sharedController {
+       if (!_ITSharedController_sharedControllers) {
+               _ITSharedController_sharedControllers = [[NSMutableDictionary alloc] init];
+       }
+       id thisController;
+       if (thisController = [_ITSharedController_sharedControllers objectForKey:NSStringFromClass(self)]) {
+               return thisController;
+       } else {
+               thisController = [[self alloc] init];
+               [_ITSharedController_sharedControllers setObject:thisController forKey:NSStringFromClass(self)];
+               return thisController;
+       }
+}
+
+@end
diff --git a/ITThreadChild.h b/ITThreadChild.h
new file mode 100644 (file)
index 0000000..a0892e7
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *     ITFoundation
+ *     ITThreadChild.h
+ *
+ *     Copyright (c) 2008 by iThink Software.
+ *     All Rights Reserved.
+ *
+ *     $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@protocol ITThreadChild <NSObject>
++ (void)runWithPorts:(NSArray *)portArray; // portArray[0] = receivePort, portArray[1] = sendPort. register an uninitialized object!
+@end
+
+@protocol ITThreadParent <NSObject>
+- (id)objectByPerformingSelector:(SEL)selector onClass:(Class)class;
+- (BOOL)registerThreadedChild:(id <ITThreadChild>)childObject; // receives an uninitialized (only alloc'd) child
+@end
+
+@interface ITThreadChild : NSObject <ITThreadChild> {
+
+}
+
++ (void)runWithPorts:(NSArray *)portArray;
+
+@end
diff --git a/ITThreadChild.m b/ITThreadChild.m
new file mode 100644 (file)
index 0000000..4b2dd85
--- /dev/null
@@ -0,0 +1,23 @@
+#import "ITThreadChild.h"
+
+@implementation ITThreadChild
+
++ (void)runWithPorts:(NSArray *)portArray {
+       NSAutoreleasePool *pool;
+       NSConnection *parentConnection;
+       id childObject;
+       
+       pool = [[NSAutoreleasePool alloc] init];
+       
+       parentConnection = [NSConnection connectionWithReceivePort:[portArray objectAtIndex:0] sendPort:[portArray objectAtIndex:1]];
+       
+       childObject = [self alloc];
+       if ([(id <ITThreadParent>)[parentConnection rootProxy] registerThreadedChild:childObject]) {
+               [[NSRunLoop currentRunLoop] run];
+       }
+       
+       [childObject release];
+       [pool release];
+}
+
+@end
diff --git a/ITUUID.h b/ITUUID.h
new file mode 100644 (file)
index 0000000..538100a
--- /dev/null
+++ b/ITUUID.h
@@ -0,0 +1,14 @@
+/*
+ *     ITFoundation
+ *     ITUUID.h
+ *
+ *     Copyright (c) 2008 by iThink Software.
+ *     All Rights Reserved.
+ *
+ *     $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+extern NSString *ITUUID();
diff --git a/ITUUID.m b/ITUUID.m
new file mode 100644 (file)
index 0000000..6e6f8e1
--- /dev/null
+++ b/ITUUID.m
@@ -0,0 +1,8 @@
+#import "ITUUID.h"
+
+NSString *ITUUID() {
+       CFUUIDRef newUUID = CFUUIDCreate(NULL);
+       CFStringRef string = CFUUIDCreateString(NULL, newUUID);
+       CFRelease(newUUID);
+       return [(NSString *)string autorelease];
+}