From: Joseph Spiros Date: Fri, 19 Sep 2008 11:56:14 +0000 (+0000) Subject: Updating ITFoundation to include updates spurred by Haven development. X-Git-Url: http://git.ithinksw.org/ITFoundation.git/commitdiff_plain/744612b5d258474e367710b870a5caaed7d11ab9 Updating ITFoundation to include updates spurred by Haven development. 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. --- diff --git a/ITCategory-NSData.h b/ITCategory-NSData.h new file mode 100644 index 0000000..68af6e3 --- /dev/null +++ b/ITCategory-NSData.h @@ -0,0 +1,21 @@ +/* + * ITFoundation + * ITCategory-NSData.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import + +@interface NSData (ITFoundationCategory) + +- (NSString *)hexadecimalRepresentation; + +- (NSData *)MD5; +- (NSData *)SHA1; + +@end diff --git a/ITCategory-NSData.m b/ITCategory-NSData.m new file mode 100644 index 0000000..0f45f68 --- /dev/null +++ b/ITCategory-NSData.m @@ -0,0 +1,36 @@ +#import "ITCategory-NSData.h" +#import +#import + +@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 diff --git a/ITCategory-NSString.h b/ITCategory-NSString.h index a0429f0..37a8572 100644 --- a/ITCategory-NSString.h +++ b/ITCategory-NSString.h @@ -18,4 +18,7 @@ - (id)initWithFourCharCode:(unsigned long)fourCharCode; - (unsigned long)fourCharCode; +- (NSData *)MD5; +- (NSData *)SHA1; + @end \ No newline at end of file diff --git a/ITCategory-NSString.m b/ITCategory-NSString.m index e08e046..6aed778 100644 --- a/ITCategory-NSString.m +++ b/ITCategory-NSString.m @@ -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]; } @@ -25,4 +26,12 @@ 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 diff --git a/ITDebug.h b/ITDebug.h index eaf6483..c53ae69 100644 --- 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 +extern NSString *ITDebugErrorPrefixForObject(id object); +extern BOOL ITDebugMode(); extern void SetITDebugMode(BOOL mode); extern void ITDebugLog(NSString *format, ...); \ No newline at end of file diff --git a/ITDebug.m b/ITDebug.m index a5666aa..578853c 100644 --- 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; } diff --git a/ITFoundation.h b/ITFoundation.h index d7f63ab..377efcb 100644 --- a/ITFoundation.h +++ b/ITFoundation.h @@ -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$ @@ -16,8 +16,13 @@ #import #import #import +#import +#import +#import +#import +#import +#import #import #import #import -#import \ No newline at end of file diff --git a/ITFoundation.xcodeproj/project.pbxproj b/ITFoundation.xcodeproj/project.pbxproj index c09ff97..3e9b6bd 100644 --- a/ITFoundation.xcodeproj/project.pbxproj +++ b/ITFoundation.xcodeproj/project.pbxproj @@ -26,32 +26,20 @@ 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 = ""; }; 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -82,6 +70,18 @@ 7CB02EB507D049BB00959EA0 /* ITCategory-NSProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSProxy.m"; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 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 = ""; }; + FABDFA530E7BBFA200BEDC10 /* ITUUID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITUUID.m; sourceTree = ""; }; + FAC0E6F00E7B61DD00698C8A /* ITSharedController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITSharedController.h; sourceTree = ""; }; + FAC0E6F10E7B61DD00698C8A /* ITSharedController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITSharedController.m; sourceTree = ""; }; + FAC0E6FC0E7B66A400698C8A /* ITThreadChild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITThreadChild.h; sourceTree = ""; }; + FAC0E6FD0E7B66A400698C8A /* ITThreadChild.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITThreadChild.m; sourceTree = ""; }; + FAC0E7D50E7B6F6900698C8A /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = ""; }; + FAC0E7D90E7B6F9D00698C8A /* ITSQLite3Database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITSQLite3Database.h; sourceTree = ""; }; + FAC0E7DA0E7B6F9D00698C8A /* ITSQLite3Database.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITSQLite3Database.m; sourceTree = ""; }; + FAD9BF000E83BF7400E110AF /* ITCategory-NSData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ITCategory-NSData.h"; sourceTree = ""; }; + FAD9BF010E83BF7400E110AF /* ITCategory-NSData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ITCategory-NSData.m"; sourceTree = ""; }; + FAD9BF0C0E83C29D00E110AF /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = /usr/lib/libcrypto.dylib; sourceTree = ""; }; /* 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; }; @@ -121,6 +123,8 @@ 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( + FAD9BF0C0E83C29D00E110AF /* libcrypto.dylib */, + FAC0E7D50E7B6F6900698C8A /* libsqlite3.dylib */, 3769DF0009A01F9000573A04 /* ApplicationServices.framework */, 0867D69BFE84028FC02AAC07 /* Foundation.framework */, ); @@ -139,11 +143,21 @@ 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 = ""; @@ -159,6 +173,8 @@ 7C0462080801DC3700433407 /* ITCategory-NSString.m */, 7C2D93BD07C2FD6700A487A9 /* ITCategory-NSBundle.h */, 7C2D93BE07C2FD6700A487A9 /* ITCategory-NSBundle.m */, + FAD9BF000E83BF7400E110AF /* ITCategory-NSData.h */, + FAD9BF010E83BF7400E110AF /* ITCategory-NSData.m */, ); name = Categories; sourceTree = ""; @@ -174,51 +190,17 @@ name = "Other Sources"; sourceTree = ""; }; - 37B1C5190612593A00F99008 /* ITDebug */ = { - isa = PBXGroup; - children = ( - 7CA50B2F054E77A00074E1D9 /* ITDebug.h */, - 7CA50B30054E77A00074E1D9 /* ITDebug.m */, - ); - name = ITDebug; - sourceTree = ""; - }; - 37B1C51F0612594A00F99008 /* ITCarbonSupport */ = { - isa = PBXGroup; - children = ( - 7C97DC2C05B614300013E85F /* ITCarbonSupport.h */, - 7C97DC2D05B614300013E85F /* ITCarbonSupport.m */, - ); - name = ITCarbonSupport; - sourceTree = ""; - }; - 37B1C5250612596000F99008 /* ITVMInfo */ = { + 37B1C52B0612597100F99008 /* Incomplete and Deprecated */ = { isa = PBXGroup; children = ( 7CA50B80054E786E0074E1D9 /* ITVirtualMemoryInfo.h */, 7CA50B7F054E786E0074E1D9 /* ITVirtualMemoryInfo.m */, - ); - name = ITVMInfo; - sourceTree = ""; - }; - 37B1C5280612596900F99008 /* ITByteStream */ = { - isa = PBXGroup; - children = ( - 7CA50B8C054E787D0074E1D9 /* ITByteStream.h */, - 7CA50B8B054E787D0074E1D9 /* ITByteStream.m */, - ); - name = ITByteStream; - sourceTree = ""; - }; - 37B1C52B0612597100F99008 /* ITXML */ = { - isa = PBXGroup; - children = ( 37B1C5740612599000F99008 /* ITXMLParser.h */, 37B1C5750612599000F99008 /* ITXMLParser.m */, 37B1C5760612599000F99008 /* ITXMLNode.h */, 37B1C5730612599000F99008 /* ITXMLNode.m */, ); - name = ITXML; + name = "Incomplete and Deprecated"; sourceTree = ""; }; /* End PBXGroup section */ @@ -237,6 +219,11 @@ 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; }; @@ -255,24 +242,6 @@ ); 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; @@ -287,18 +256,12 @@ 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 */, ); @@ -338,6 +301,11 @@ 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 index 0000000..ed13477 --- /dev/null +++ b/ITSQLite3Database.h @@ -0,0 +1,41 @@ +/* + * ITFoundation + * ITSQLite3Database.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import +#import + +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 index 0000000..1984e6d --- /dev/null +++ b/ITSQLite3Database.m @@ -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 index 0000000..3b93610 --- /dev/null +++ b/ITSharedController.h @@ -0,0 +1,20 @@ +/* + * ITFoundation + * ITSharedController.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import + +@interface ITSharedController : NSObject { + +} + ++ (id)sharedController; + +@end diff --git a/ITSharedController.m b/ITSharedController.m new file mode 100644 index 0000000..1887165 --- /dev/null +++ b/ITSharedController.m @@ -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 index 0000000..a0892e7 --- /dev/null +++ b/ITThreadChild.h @@ -0,0 +1,29 @@ +/* + * ITFoundation + * ITThreadChild.h + * + * Copyright (c) 2008 by iThink Software. + * All Rights Reserved. + * + * $Id$ + * + */ + +#import + +@protocol ITThreadChild ++ (void)runWithPorts:(NSArray *)portArray; // portArray[0] = receivePort, portArray[1] = sendPort. register an uninitialized object! +@end + +@protocol ITThreadParent +- (id)objectByPerformingSelector:(SEL)selector onClass:(Class)class; +- (BOOL)registerThreadedChild:(id )childObject; // receives an uninitialized (only alloc'd) child +@end + +@interface ITThreadChild : NSObject { + +} + ++ (void)runWithPorts:(NSArray *)portArray; + +@end diff --git a/ITThreadChild.m b/ITThreadChild.m new file mode 100644 index 0000000..4b2dd85 --- /dev/null +++ b/ITThreadChild.m @@ -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 )[parentConnection rootProxy] registerThreadedChild:childObject]) { + [[NSRunLoop currentRunLoop] run]; + } + + [childObject release]; + [pool release]; +} + +@end diff --git a/ITUUID.h b/ITUUID.h new file mode 100644 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 + +extern NSString *ITUUID(); diff --git a/ITUUID.m b/ITUUID.m new file mode 100644 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]; +}