--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
- (id)initWithFourCharCode:(unsigned long)fourCharCode;
- (unsigned long)fourCharCode;
+- (NSData *)MD5;
+- (NSData *)SHA1;
+
@end
\ No newline at end of file
#import "ITCategory-NSString.h"
+#import "ITCategory-NSData.h"
@implementation NSString (ITFoundationCategory)
}
- (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
*
* Functions for logging debugging information intelligently.
*
- * Copyright (c) 2005 by iThink Software.
+ * Copyright (c) 2008 by iThink Software.
* All Rights Reserved.
*
* $Id$
#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
#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;
}
*
* 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
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 */
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;
};
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
--- /dev/null
+/*
+ * ITFoundation
+ * ITSharedController.h
+ *
+ * Copyright (c) 2008 by iThink Software.
+ * All Rights Reserved.
+ *
+ * $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface ITSharedController : NSObject {
+
+}
+
++ (id)sharedController;
+
+@end
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
--- /dev/null
+/*
+ * ITFoundation
+ * ITUUID.h
+ *
+ * Copyright (c) 2008 by iThink Software.
+ * All Rights Reserved.
+ *
+ * $Id$
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+extern NSString *ITUUID();
--- /dev/null
+#import "ITUUID.h"
+
+NSString *ITUUID() {
+ CFUUIDRef newUUID = CFUUIDCreate(NULL);
+ CFStringRef string = CFUUIDCreateString(NULL, newUUID);
+ CFRelease(newUUID);
+ return [(NSString *)string autorelease];
+}