Added support for newer operating systems and dropped Dropbox (funny to say).
@ -68,6 +68,7 @@ extern NSString * const MGMFFilter;
 | 
			
		||||
	int currentPlugInIndex;
 | 
			
		||||
	
 | 
			
		||||
	NSLock *uploadLock;
 | 
			
		||||
	NSMutableArray *multiUploadLinks;
 | 
			
		||||
	NSMutableArray *uploads;
 | 
			
		||||
}
 | 
			
		||||
+ (id)sharedController;
 | 
			
		||||
@ -121,6 +122,7 @@ extern NSString * const MGMFFilter;
 | 
			
		||||
- (NSMutableArray *)uploads;
 | 
			
		||||
- (NSDictionary *)uploadForPath:(NSString *)thePath;
 | 
			
		||||
- (void)addPathToUploads:(NSString *)thePath isAutomatic:(BOOL)isAutomatic;
 | 
			
		||||
- (void)addPathToUploads:(NSString *)thePath isAutomatic:(BOOL)isAutomatic multiUpload:(int)multiUploadState;
 | 
			
		||||
- (void)processNextUpload;
 | 
			
		||||
- (void)upload:(NSString *)thePath receivedError:(NSError *)theError;
 | 
			
		||||
- (void)uploadFinished:(NSString *)thePath url:(NSURL *)theURL;
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
#import <Growl/GrowlApplicationBridge.h>
 | 
			
		||||
#import <Carbon/Carbon.h>
 | 
			
		||||
 | 
			
		||||
NSString * const MGMCopyright = @"Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/";
 | 
			
		||||
NSString * const MGMCopyright = @"Copyright (c) 2015 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/  All rights reserved.";
 | 
			
		||||
NSString * const MGMVersion = @"MGMVersion";
 | 
			
		||||
NSString * const MGMLaunchCount = @"MGMLaunchCount";
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,7 @@ NSString * const MGMKCName = @"CocoaShare";
 | 
			
		||||
 | 
			
		||||
NSString * const MGMUPath = @"path";
 | 
			
		||||
NSString * const MGMUAutomatic = @"automatic";
 | 
			
		||||
NSString * const MGMUMultiUpload = @"multiUpload";
 | 
			
		||||
NSString * const MGMNSStringPboardType = @"NSStringPboardType";
 | 
			
		||||
NSString * const MGMNSPasteboardTypeString = @"public.utf8-plain-text";
 | 
			
		||||
 | 
			
		||||
@ -118,7 +119,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if ([defaults boolForKey:MGMStartup])
 | 
			
		||||
		[[MGMLoginItems items] addSelf];
 | 
			
		||||
		[[MGMLoginItems items] addThisApplication];
 | 
			
		||||
	
 | 
			
		||||
	NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
	if ([manager fileExistsAtPath:[[MGMUser applicationSupportPath] stringByAppendingPathComponent:MGMHistoryPlist]]) {
 | 
			
		||||
@ -192,7 +193,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithInt:1] forKey:MGMLaunchCount];
 | 
			
		||||
	
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithInt:([[MGMSystemInfo info] isUIElement] ? 2 : 0)] forKey:MGMDisplay];
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithBool:[[MGMLoginItems items] selfExists]] forKey:MGMStartup];
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithBool:[[MGMLoginItems items] thisApplicationExists]] forKey:MGMStartup];
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithInt:0] forKey:MGMUploadName];
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithInt:5] forKey:MGMHistoryCount];
 | 
			
		||||
	[defaults setObject:[NSNumber numberWithInt:5] forKey:MGMUploadLimit];
 | 
			
		||||
@ -307,8 +308,14 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	if (statusItem==nil) {
 | 
			
		||||
		menuItem = [[MGMMenuItem alloc] initWithFrame:NSZeroRect];
 | 
			
		||||
		[menuItem setDelegate:self];
 | 
			
		||||
		[menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
		[menuItem setAlternateImage:[NSImage imageNamed:@"menuiconselected"]];
 | 
			
		||||
        NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
 | 
			
		||||
        if ([osxMode isEqualTo:@"Dark"]) {
 | 
			
		||||
            [menuItem setImage:[NSImage imageNamed:@"menuiconselected"]];
 | 
			
		||||
            [menuItem setAlternateImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
        } else {
 | 
			
		||||
            [menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
            [menuItem setAlternateImage:[NSImage imageNamed:@"menuiconselected"]];
 | 
			
		||||
        }
 | 
			
		||||
		[menuItem setToolTip:@"CocoaShare"];
 | 
			
		||||
		statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain];
 | 
			
		||||
		[statusItem setView:menuItem];
 | 
			
		||||
@ -370,7 +377,12 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	[menuItem setImage:[NSImage imageNamed:@"menuicondrag"]];
 | 
			
		||||
}
 | 
			
		||||
- (void)menuDraggingExited:(id)sender {
 | 
			
		||||
	[menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
    NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
 | 
			
		||||
    if ([osxMode isEqualTo:@"Dark"]) {
 | 
			
		||||
        [menuItem setImage:[NSImage imageNamed:@"menuiconselected"]];
 | 
			
		||||
    } else {
 | 
			
		||||
        [menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
- (void)menu:(id)sender droppedFiles:(NSArray *)files {
 | 
			
		||||
	NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
@ -384,7 +396,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
				[alert runModal];
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			[self addPathToUploads:[files objectAtIndex:i] isAutomatic:NO];
 | 
			
		||||
			[self addPathToUploads:[files objectAtIndex:i] isAutomatic:NO multiUpload:([files count]==1 ? 0 : (i==0 ? 1 : (i==[files count]-1 ? 3 : 2)))];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -456,7 +468,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	int returnCode = [panel runModal];
 | 
			
		||||
	if (returnCode==NSOKButton) {
 | 
			
		||||
		for (int i=0; i<[[panel URLs] count]; i++) {
 | 
			
		||||
			[self addPathToUploads:[[[panel URLs] objectAtIndex:i] path] isAutomatic:NO];
 | 
			
		||||
			[self addPathToUploads:[[[panel URLs] objectAtIndex:i] path] isAutomatic:NO  multiUpload:([[panel URLs] count]==1 ? 0 : (i==0 ? 1 : (i==[[panel URLs] count]-1 ? 3 : 2)))];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	[self resignFront];
 | 
			
		||||
@ -469,7 +481,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
}
 | 
			
		||||
- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)theFiles {
 | 
			
		||||
	for (int i=0; i<[theFiles count]; i++) {
 | 
			
		||||
		[self addPathToUploads:[theFiles objectAtIndex:i] isAutomatic:NO];
 | 
			
		||||
		[self addPathToUploads:[theFiles objectAtIndex:i] isAutomatic:NO  multiUpload:([theFiles count]==1 ? 0 : (i==0 ? 1 : (i==[theFiles count]-1 ? 3 : 2)))];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -486,10 +498,10 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	[self becomeFront:[preferences preferencesWindow]];
 | 
			
		||||
}
 | 
			
		||||
- (IBAction)donate:(id)sender {
 | 
			
		||||
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=U9LTDN57NPZ44"]];
 | 
			
		||||
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://mrgeckosmedia.com/donate?purpose=cocoashare"]];
 | 
			
		||||
}
 | 
			
		||||
- (IBAction)quit:(id)sender {
 | 
			
		||||
	[[MGMLoginItems items] removeSelf];
 | 
			
		||||
	[[MGMLoginItems items] removeThisApplication];
 | 
			
		||||
	[[NSApplication sharedApplication] terminate:self];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -693,7 +705,17 @@ static MGMController *MGMSharedController;
 | 
			
		||||
	}
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)addPathToUploads:(NSString *)thePath isAutomatic:(BOOL)isAutomatic {
 | 
			
		||||
	[self addPathToUploads:thePath isAutomatic:isAutomatic multiUpload:0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//No multi uploads = 0
 | 
			
		||||
//First upload = 1
 | 
			
		||||
//Inbetween upload = 2
 | 
			
		||||
//Last upload = 3
 | 
			
		||||
//HTML = 4
 | 
			
		||||
- (void)addPathToUploads:(NSString *)thePath isAutomatic:(BOOL)isAutomatic multiUpload:(int)multiUploadState {
 | 
			
		||||
	[uploadLock lock];
 | 
			
		||||
	if ([self uploadForPath:thePath]==nil) {
 | 
			
		||||
		if ([currentPlugIn respondsToSelector:@selector(allowedExtensions)]) {
 | 
			
		||||
@ -705,7 +727,7 @@ static MGMController *MGMSharedController;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		[uploads addObject:[NSDictionary dictionaryWithObjectsAndKeys:thePath, MGMUPath, [NSNumber numberWithBool:isAutomatic], MGMUAutomatic, nil]];
 | 
			
		||||
		[uploads addObject:[NSDictionary dictionaryWithObjectsAndKeys:thePath, MGMUPath, [NSNumber numberWithBool:isAutomatic], MGMUAutomatic, [NSNumber numberWithInt:multiUploadState], MGMUMultiUpload, nil]];
 | 
			
		||||
		if ([uploads count]==1)
 | 
			
		||||
			[self processNextUpload];
 | 
			
		||||
	}
 | 
			
		||||
@ -730,6 +752,11 @@ static MGMController *MGMSharedController;
 | 
			
		||||
		}
 | 
			
		||||
		NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
		NSDictionary *upload = [uploads objectAtIndex:0];
 | 
			
		||||
		if ([[upload objectForKey:MGMUMultiUpload] intValue]==1) {
 | 
			
		||||
			[multiUploadLinks release];
 | 
			
		||||
			multiUploadLinks = [NSMutableArray new];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (![manager fileExistsAtPath:[upload objectForKey:MGMUPath]]) {
 | 
			
		||||
			[uploads removeObject:upload];
 | 
			
		||||
			[self processNextUpload];
 | 
			
		||||
@ -744,7 +771,12 @@ static MGMController *MGMSharedController;
 | 
			
		||||
			name = [randomizedName stringByAppendingPathExtension:[name pathExtension]];
 | 
			
		||||
		[currentPlugIn sendFileAtPath:[upload objectForKey:MGMUPath] withName:name];
 | 
			
		||||
	} else {
 | 
			
		||||
		[menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
        NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
 | 
			
		||||
        if ([osxMode isEqualTo:@"Dark"]) {
 | 
			
		||||
            [menuItem setImage:[NSImage imageNamed:@"menuiconselected"]];
 | 
			
		||||
        } else {
 | 
			
		||||
            [menuItem setImage:[NSImage imageNamed:@"menuicon"]];
 | 
			
		||||
        }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
- (void)upload:(NSString *)thePath receivedError:(NSError *)theError {
 | 
			
		||||
@ -773,6 +805,37 @@ static MGMController *MGMSharedController;
 | 
			
		||||
		[pboard setString:[theURL absoluteString] forType:MGMNSStringPboardType];
 | 
			
		||||
		[pboard setString:[theURL absoluteString] forType:MGMNSPasteboardTypeString];
 | 
			
		||||
		[self addURLToHistory:theURL];
 | 
			
		||||
		
 | 
			
		||||
		int multiUpload = [[upload objectForKey:MGMUMultiUpload] intValue];
 | 
			
		||||
		if (multiUpload>=1 && multiUpload!=4) {
 | 
			
		||||
			[multiUploadLinks addObject:theURL];
 | 
			
		||||
		}
 | 
			
		||||
		if (multiUpload==3) {
 | 
			
		||||
			NSString *randomizedName = [[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] MD5];
 | 
			
		||||
			NSString *htmlPath = [NSString stringWithFormat:@"/tmp/%@.htm", randomizedName];
 | 
			
		||||
			[[NSFileManager defaultManager] createFileAtPath:htmlPath contents:nil attributes:nil];
 | 
			
		||||
			NSFileHandle *multiUploadHtml = [NSFileHandle fileHandleForWritingAtPath:htmlPath];
 | 
			
		||||
			[multiUploadHtml writeData:[@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
 | 
			
		||||
									  "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\">\n"
 | 
			
		||||
									  "<head><style>img {max-width: 100%;}</style><title>Multiple Upload Links</title></head><body>\n" dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
			for (int i=0; i<[multiUploadLinks count]; i++) {
 | 
			
		||||
				NSURL *link = [multiUploadLinks objectAtIndex:i];
 | 
			
		||||
				NSString *linkString = [link absoluteString];
 | 
			
		||||
				NSArray *imageExtensions = [NSArray arrayWithObjects:@"jpg", @"jpeg", @"png", @"bmp", @"gif", nil];
 | 
			
		||||
				if ([imageExtensions containsObject:[[link pathExtension] lowercaseString]]) {
 | 
			
		||||
					[multiUploadHtml writeData:[[NSString stringWithFormat:@"<a href=\"%@\"><img src=\"%@\"></a><br />\n", linkString, linkString] dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
				} else {
 | 
			
		||||
					[multiUploadHtml writeData:[[NSString stringWithFormat:@"<a href=\"%@\">%@</a><br />\n", linkString, linkString] dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			[multiUploadHtml writeData:[@"</body></html>" dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
			[multiUploadHtml closeFile];
 | 
			
		||||
			[self addPathToUploads:htmlPath isAutomatic:YES multiUpload:4];
 | 
			
		||||
		}
 | 
			
		||||
		if (multiUpload==4) {
 | 
			
		||||
			[[NSFileManager defaultManager] removeItemAtPath:[upload objectForKey:MGMUPath]];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		[uploadLock lock];
 | 
			
		||||
		[uploads removeObject:upload];
 | 
			
		||||
		[self processNextUpload];
 | 
			
		||||
 | 
			
		||||
@ -1,24 +1,76 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMLoginItems.h
 | 
			
		||||
//  Exhaust
 | 
			
		||||
//  Conmote
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 8/7/10.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//  Created by Mr. Gecko on 8/14/13.
 | 
			
		||||
//  Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
//  Permission to use, copy, modify, and/or distribute this software for any purpose
 | 
			
		||||
//  with or without fee is hereby granted, provided that the above copyright notice
 | 
			
		||||
//  and this permission notice appear in all copies.
 | 
			
		||||
//
 | 
			
		||||
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
			
		||||
//  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
//  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
 | 
			
		||||
//  OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
			
		||||
//  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 | 
			
		||||
//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Cocoa/Cocoa.h>
 | 
			
		||||
#import <CoreServices/CoreServices.h>
 | 
			
		||||
 | 
			
		||||
@class MGMLoginItems, MGMPathSubscriber;
 | 
			
		||||
 | 
			
		||||
enum MGMLoginItemType {
 | 
			
		||||
	MGMLoginItemShared = 0,
 | 
			
		||||
	MGMLoginItemInfo = 1
 | 
			
		||||
} typedef MGMLoginItemType;
 | 
			
		||||
 | 
			
		||||
@interface MGMLoginItem : NSObject {
 | 
			
		||||
	MGMLoginItems *loginItems;
 | 
			
		||||
	LSSharedFileListItemRef itemRef;
 | 
			
		||||
	NSDictionary *itemInfo;
 | 
			
		||||
	MGMLoginItemType type;
 | 
			
		||||
	
 | 
			
		||||
	NSURL *URL;
 | 
			
		||||
	BOOL hideOnLaunch;
 | 
			
		||||
}
 | 
			
		||||
+ (id)itemWithItemRef:(LSSharedFileListItemRef)theItemRef loginItems:(MGMLoginItems *)theLoginItems;
 | 
			
		||||
- (id)initWithItemRef:(LSSharedFileListItemRef)theItemRef loginItems:(MGMLoginItems *)theLoginItems;
 | 
			
		||||
+ (id)itemWithItemInfo:(NSDictionary *)theItemInfo loginItems:(MGMLoginItems *)theLoginItems;
 | 
			
		||||
- (id)initWithItemInfo:(NSDictionary *)theItemInfo loginItems:(MGMLoginItems *)theLoginItems;
 | 
			
		||||
- (LSSharedFileListItemRef)itemRef;
 | 
			
		||||
- (BOOL)setItemRef:(LSSharedFileListItemRef)theItemRef;
 | 
			
		||||
- (NSDictionary *)itemInfo;
 | 
			
		||||
- (BOOL)setItemInfo:(NSDictionary *)theItemInfo;
 | 
			
		||||
- (MGMLoginItemType)type;
 | 
			
		||||
- (void)setURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)URL;
 | 
			
		||||
- (void)setPath:(NSString *)thePath;
 | 
			
		||||
- (NSString *)path;
 | 
			
		||||
- (void)setHidesOnLaunch:(BOOL)doesHide;
 | 
			
		||||
- (BOOL)hideOnLaunch;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface MGMLoginItems : NSObject {
 | 
			
		||||
	NSMutableDictionary *loginItems;
 | 
			
		||||
	BOOL sharedSupported;
 | 
			
		||||
	BOOL updated;
 | 
			
		||||
	LSSharedFileListRef itemsRef;
 | 
			
		||||
	CFRunLoopRef runLoop;
 | 
			
		||||
	NSMutableArray *loginItems;
 | 
			
		||||
	MGMPathSubscriber *subcriber;
 | 
			
		||||
}
 | 
			
		||||
+ (id)sharedItems;
 | 
			
		||||
+ (id)items;
 | 
			
		||||
- (NSArray *)paths;
 | 
			
		||||
- (BOOL)selfExists;
 | 
			
		||||
- (BOOL)addSelf;
 | 
			
		||||
- (BOOL)removeSelf;
 | 
			
		||||
- (NSArray *)loginItems;
 | 
			
		||||
- (MGMLoginItem *)itemForPath:(NSString *)thePath;
 | 
			
		||||
- (BOOL)thisApplicationExists;
 | 
			
		||||
- (BOOL)addThisApplication;
 | 
			
		||||
- (BOOL)removeThisApplication;
 | 
			
		||||
- (BOOL)exists:(NSString *)thePath;
 | 
			
		||||
- (BOOL)add:(NSString *)thePath;
 | 
			
		||||
- (BOOL)add:(NSString *)thePath hide:(BOOL)shouldHide;
 | 
			
		||||
- (BOOL)add:(NSString *)thePath hideOnLaunch:(BOOL)doesHide;
 | 
			
		||||
- (BOOL)remove:(NSString *)thePath;
 | 
			
		||||
- (void)_save;
 | 
			
		||||
- (BOOL)removeItem:(MGMLoginItem *)theItem;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,89 +1,398 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMLoginItems.m
 | 
			
		||||
//  Exhaust
 | 
			
		||||
//  Conmote
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 8/7/10.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//  Created by Mr. Gecko on 8/14/13.
 | 
			
		||||
//  Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
//  Permission to use, copy, modify, and/or distribute this software for any purpose
 | 
			
		||||
//  with or without fee is hereby granted, provided that the above copyright notice
 | 
			
		||||
//  and this permission notice appear in all copies.
 | 
			
		||||
//
 | 
			
		||||
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
			
		||||
//  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
//  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
 | 
			
		||||
//  OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
			
		||||
//  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 | 
			
		||||
//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MGMLoginItems.h"
 | 
			
		||||
#import "MGMPathSubscriber.h"
 | 
			
		||||
 | 
			
		||||
NSString * const MGMLoginItemsPath = @"~/Library/Preferences/loginwindow.plist";
 | 
			
		||||
NSString * const MGMItemsKey = @"AutoLaunchedApplicationDictionary";
 | 
			
		||||
NSString * const MGMPathKey = @"Path";
 | 
			
		||||
NSString * const MGMHideKey = @"Hide";
 | 
			
		||||
NSString * const MGMLoginItemsKey = @"AutoLaunchedApplicationDictionary";
 | 
			
		||||
NSString * const MGMLoginItemPathKey = @"Path";
 | 
			
		||||
NSString * const MGMLoginItemHideKey = @"Hide";
 | 
			
		||||
NSString * const MGMLoginItemHideProperty = @"com.apple.loginitem.HideOnLaunch";
 | 
			
		||||
NSString * const MGMLoginItemsUpdated = @"MGMLoginItemsUpdated";
 | 
			
		||||
 | 
			
		||||
@interface MGMLoginItems (MGMPrivate)
 | 
			
		||||
- (void)updateItem:(MGMLoginItem *)theItem;
 | 
			
		||||
- (void)updateItems;
 | 
			
		||||
- (void)saveLoginWindowItems;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void MGMLoginItemsFileListChanged(LSSharedFileListRef inList, void *context) {
 | 
			
		||||
	[(MGMLoginItems *)context updateItems];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@implementation MGMLoginItem
 | 
			
		||||
+ (id)itemWithItemRef:(LSSharedFileListItemRef)theItemRef loginItems:(MGMLoginItems *)theLoginItems {
 | 
			
		||||
	return [[[self alloc] initWithItemRef:theItemRef loginItems:theLoginItems] autorelease];
 | 
			
		||||
}
 | 
			
		||||
- (id)initWithItemRef:(LSSharedFileListItemRef)theItemRef loginItems:(MGMLoginItems *)theLoginItems {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		loginItems = theLoginItems;
 | 
			
		||||
		if (theItemRef==NULL) {
 | 
			
		||||
			NSLog(@"MGMLoginItem: Invalid item reference.");
 | 
			
		||||
			[self release];
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
		itemRef = (LSSharedFileListItemRef)CFRetain(theItemRef);
 | 
			
		||||
		NSURL *itemURL = nil;
 | 
			
		||||
		LSSharedFileListItemResolve(itemRef, 0, (CFURLRef *)&itemURL, NULL);
 | 
			
		||||
		if (itemURL==nil) {
 | 
			
		||||
			NSLog(@"MGMLoginItem: Unable to resolve item location.");
 | 
			
		||||
			[self release];
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
		URL = itemURL;
 | 
			
		||||
		NSNumber *property = (NSNumber *)LSSharedFileListItemCopyProperty(itemRef, (CFStringRef)MGMLoginItemHideProperty);
 | 
			
		||||
		hideOnLaunch = [property boolValue];
 | 
			
		||||
		[property release];
 | 
			
		||||
		type = MGMLoginItemShared;
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (id)itemWithItemInfo:(NSDictionary *)theItemInfo loginItems:(MGMLoginItems *)theLoginItems {
 | 
			
		||||
	return [[[self alloc] initWithItemInfo:theItemInfo loginItems:theLoginItems] autorelease];
 | 
			
		||||
}
 | 
			
		||||
- (id)initWithItemInfo:(NSDictionary *)theItemInfo loginItems:(MGMLoginItems *)theLoginItems {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		loginItems = theLoginItems;
 | 
			
		||||
		if (theItemInfo==nil || [theItemInfo objectForKey:MGMLoginItemPathKey]==nil) {
 | 
			
		||||
			NSLog(@"MGMLoginItem: Invalid item info.");
 | 
			
		||||
			[self release];
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
		itemInfo = [theItemInfo retain];
 | 
			
		||||
		NSURL *itemURL = [NSURL fileURLWithPath:[itemInfo objectForKey:MGMLoginItemPathKey]];
 | 
			
		||||
		if (itemURL==nil) {
 | 
			
		||||
			NSLog(@"MGMLoginItem: Unable to resolve item path.");
 | 
			
		||||
			[self release];
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
		URL = [itemURL retain];
 | 
			
		||||
		hideOnLaunch = [[itemInfo objectForKey:MGMLoginItemHideKey] boolValue];
 | 
			
		||||
		type = MGMLoginItemInfo;
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
	[URL release];
 | 
			
		||||
	if (itemRef!=NULL)
 | 
			
		||||
		CFRelease(itemRef);
 | 
			
		||||
	[itemInfo release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
- (LSSharedFileListItemRef)itemRef {
 | 
			
		||||
	return itemRef;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)setItemRef:(LSSharedFileListItemRef)theItemRef {
 | 
			
		||||
	if (theItemRef==NULL) {
 | 
			
		||||
		NSLog(@"MGMLoginItem: Invalid item reference.");
 | 
			
		||||
		return NO;
 | 
			
		||||
	}
 | 
			
		||||
	NSURL *itemURL = nil;
 | 
			
		||||
	LSSharedFileListItemResolve(theItemRef, 0, (CFURLRef *)&itemURL, NULL);
 | 
			
		||||
	if (itemURL==nil) {
 | 
			
		||||
		CFRelease(theItemRef);
 | 
			
		||||
		NSLog(@"MGMLoginItem: Unable to resolve item path.");
 | 
			
		||||
		return NO;
 | 
			
		||||
	}
 | 
			
		||||
	CFRelease(itemRef);
 | 
			
		||||
	itemRef = (LSSharedFileListItemRef)CFRetain(theItemRef);
 | 
			
		||||
	[URL release];
 | 
			
		||||
	URL = itemURL;
 | 
			
		||||
	NSNumber *property = (NSNumber *)LSSharedFileListItemCopyProperty(itemRef, (CFStringRef)MGMLoginItemHideProperty);
 | 
			
		||||
	hideOnLaunch = [property boolValue];
 | 
			
		||||
	[property release];
 | 
			
		||||
	type = MGMLoginItemShared;
 | 
			
		||||
	[itemInfo release];
 | 
			
		||||
	itemInfo = nil;
 | 
			
		||||
	return YES;
 | 
			
		||||
}
 | 
			
		||||
- (NSDictionary *)itemInfo {
 | 
			
		||||
	return itemInfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
	return [NSString stringWithFormat:@"<%@:%p %@>", NSStringFromClass([self class]), self, [self path]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)setItemInfo:(NSDictionary *)theItemInfo {
 | 
			
		||||
	if (theItemInfo==nil && [theItemInfo objectForKey:MGMLoginItemPathKey]) {
 | 
			
		||||
		NSLog(@"MGMLoginItem: Invalid item info.");
 | 
			
		||||
		return NO;
 | 
			
		||||
	}
 | 
			
		||||
	NSURL *itemURL = [NSURL fileURLWithPath:[theItemInfo objectForKey:MGMLoginItemPathKey]];
 | 
			
		||||
	if (itemURL==nil) {
 | 
			
		||||
		NSLog(@"MGMLoginItem: Unable to find item path.");
 | 
			
		||||
		return NO;
 | 
			
		||||
	}
 | 
			
		||||
	itemInfo = [theItemInfo retain];
 | 
			
		||||
	URL = [itemURL retain];
 | 
			
		||||
	hideOnLaunch = [[itemInfo objectForKey:MGMLoginItemHideKey] boolValue];
 | 
			
		||||
	type = MGMLoginItemInfo;
 | 
			
		||||
	CFRelease(itemRef);
 | 
			
		||||
	itemRef = NULL;
 | 
			
		||||
	return YES;
 | 
			
		||||
}
 | 
			
		||||
- (MGMLoginItemType)type {
 | 
			
		||||
	return  type;
 | 
			
		||||
}
 | 
			
		||||
- (void)setURL:(NSURL *)theURL {
 | 
			
		||||
	[URL release];
 | 
			
		||||
	URL = [theURL retain];
 | 
			
		||||
	[loginItems updateItem:self];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)URL {
 | 
			
		||||
	return URL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setPath:(NSString *)thePath {
 | 
			
		||||
	[self setURL:[NSURL fileURLWithPath:thePath]];
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)path {
 | 
			
		||||
	return [URL path];
 | 
			
		||||
}
 | 
			
		||||
- (void)setHidesOnLaunch:(BOOL)doesHide {
 | 
			
		||||
	hideOnLaunch = doesHide;
 | 
			
		||||
	[loginItems updateItem:self];
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)hideOnLaunch {
 | 
			
		||||
	return hideOnLaunch;
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
static MGMLoginItems *MGMSharedLoginItems;
 | 
			
		||||
 | 
			
		||||
@implementation MGMLoginItems
 | 
			
		||||
+ (id)sharedItems {
 | 
			
		||||
	if (MGMSharedLoginItems==nil)
 | 
			
		||||
		MGMSharedLoginItems = [MGMLoginItems new];
 | 
			
		||||
	return MGMSharedLoginItems;
 | 
			
		||||
}
 | 
			
		||||
+ (id)items {
 | 
			
		||||
	return [[[self alloc] init] autorelease];
 | 
			
		||||
}
 | 
			
		||||
- (id)init {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		loginItems = [[NSMutableDictionary dictionaryWithContentsOfFile:[MGMLoginItemsPath stringByExpandingTildeInPath]] retain];
 | 
			
		||||
		loginItems = [NSMutableArray new];
 | 
			
		||||
		
 | 
			
		||||
		sharedSupported = (NSFoundationVersionNumber>=677.00/*NSFoundationVersionNumber10_5*/);
 | 
			
		||||
		
 | 
			
		||||
		if (sharedSupported) {
 | 
			
		||||
			itemsRef = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, NULL);
 | 
			
		||||
			UInt32 outSnapshotSeed = 0;
 | 
			
		||||
			NSArray *items = [(NSArray *)LSSharedFileListCopySnapshot(itemsRef, &outSnapshotSeed) autorelease];
 | 
			
		||||
			for (int i=0; i<[items count]; i++) {
 | 
			
		||||
				LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[items objectAtIndex:i];
 | 
			
		||||
				MGMLoginItem *item = [MGMLoginItem itemWithItemRef:itemRef loginItems:self];
 | 
			
		||||
				if (item!=nil)
 | 
			
		||||
					[loginItems addObject:item];
 | 
			
		||||
			}
 | 
			
		||||
			runLoop = CFRunLoopGetCurrent();
 | 
			
		||||
			LSSharedFileListAddObserver(itemsRef, runLoop, kCFRunLoopDefaultMode, &MGMLoginItemsFileListChanged, (void *)self);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		subcriber = [MGMPathSubscriber new];
 | 
			
		||||
		[subcriber setDelegate:self];
 | 
			
		||||
		[subcriber addPath:[MGMLoginItemsPath stringByExpandingTildeInPath] fileOptions:MGMFOWrite | MGMFODelete];
 | 
			
		||||
		
 | 
			
		||||
		NSDictionary *loginWindowItems = [NSDictionary dictionaryWithContentsOfFile:[MGMLoginItemsPath stringByExpandingTildeInPath]];
 | 
			
		||||
		NSArray *items = [loginWindowItems objectForKey:MGMLoginItemsKey];
 | 
			
		||||
		for (unsigned int i=0; i<[items count]; i++) {
 | 
			
		||||
			NSDictionary *itemInfo = [items objectAtIndex:i];
 | 
			
		||||
			if (![self exists:[itemInfo objectForKey:MGMLoginItemPathKey]]) {
 | 
			
		||||
				MGMLoginItem *item = [MGMLoginItem itemWithItemInfo:itemInfo loginItems:self];
 | 
			
		||||
				if (item!=nil)
 | 
			
		||||
					[loginItems addObject:item];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
	if (sharedSupported) {
 | 
			
		||||
		LSSharedFileListRemoveObserver(itemsRef, runLoop, kCFRunLoopDefaultMode, &MGMLoginItemsFileListChanged, (void *)self);
 | 
			
		||||
		CFRelease(itemsRef);
 | 
			
		||||
	}
 | 
			
		||||
	[loginItems release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSArray *)paths {
 | 
			
		||||
	NSMutableArray *returnApps = [NSMutableArray array];
 | 
			
		||||
	NSArray *applications = [loginItems objectForKey:MGMItemsKey];
 | 
			
		||||
	for (int i=0; i<[applications count]; i++) {
 | 
			
		||||
		[returnApps addObject:[[applications objectAtIndex:i] objectForKey:MGMPathKey]];
 | 
			
		||||
- (void)updateItem:(MGMLoginItem *)theItem {
 | 
			
		||||
	if ([theItem type]==MGMLoginItemShared && sharedSupported) {
 | 
			
		||||
		NSMutableDictionary *itemsToSet = [NSMutableDictionary dictionary];
 | 
			
		||||
		NSMutableArray *itemsToClear = [NSMutableArray array];
 | 
			
		||||
		if ([theItem hideOnLaunch])
 | 
			
		||||
			[itemsToSet setObject:[NSNumber numberWithBool:YES] forKey:MGMLoginItemHideProperty];
 | 
			
		||||
		else
 | 
			
		||||
			[itemsToClear addObject:MGMLoginItemHideProperty];
 | 
			
		||||
		LSSharedFileListItemRef afterItemRef = kLSSharedFileListItemBeforeFirst;
 | 
			
		||||
		MGMLoginItem *lastItem = nil;
 | 
			
		||||
		for (unsigned int i=0; i<[loginItems count]; i++) {
 | 
			
		||||
			MGMLoginItem *item = [loginItems objectAtIndex:i];
 | 
			
		||||
			if ([item type]==MGMLoginItemShared) {
 | 
			
		||||
				if (lastItem==nil && [theItem isEqual:item]) {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				if ([theItem isEqual:item]) {
 | 
			
		||||
					afterItemRef = [lastItem itemRef];
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				lastItem = item;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		LSSharedFileListItemRef newItem = LSSharedFileListInsertItemURL(itemsRef, afterItemRef, NULL, NULL, (CFURLRef)[theItem URL], (CFDictionaryRef)itemsToSet, (CFArrayRef)itemsToClear);
 | 
			
		||||
		LSSharedFileListItemRef oldItem = (LSSharedFileListItemRef)CFRetain([theItem itemRef]);
 | 
			
		||||
		if ([theItem setItemRef:newItem] && LSSharedFileListItemGetID(newItem)!=LSSharedFileListItemGetID(oldItem)) {
 | 
			
		||||
			LSSharedFileListItemRemove(itemsRef, oldItem);
 | 
			
		||||
		}
 | 
			
		||||
		CFRelease(newItem);
 | 
			
		||||
		CFRelease(oldItem);
 | 
			
		||||
		updated = YES;
 | 
			
		||||
	} else {
 | 
			
		||||
		[self saveLoginWindowItems];
 | 
			
		||||
	}
 | 
			
		||||
	return returnApps;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)selfExists {
 | 
			
		||||
- (NSArray *)loginItems {
 | 
			
		||||
	return loginItems;
 | 
			
		||||
}
 | 
			
		||||
- (MGMLoginItem *)itemForPath:(NSString *)thePath {
 | 
			
		||||
	for (unsigned int i=0; i<[loginItems count]; i++) {
 | 
			
		||||
		MGMLoginItem *item = [loginItems objectAtIndex:i];
 | 
			
		||||
		if ([[item path] isEqual:thePath])
 | 
			
		||||
			return item;
 | 
			
		||||
	}
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)thisApplicationExists {
 | 
			
		||||
	return [self exists:[[NSBundle mainBundle] bundlePath]];
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)addSelf {
 | 
			
		||||
- (BOOL)addThisApplication {
 | 
			
		||||
	return [self add:[[NSBundle mainBundle] bundlePath]];
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)removeSelf {
 | 
			
		||||
- (BOOL)removeThisApplication {
 | 
			
		||||
	return [self remove:[[NSBundle mainBundle] bundlePath]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)exists:(NSString *)thePath {
 | 
			
		||||
	NSArray *applications = [loginItems objectForKey:MGMItemsKey];
 | 
			
		||||
	for (int i=0; i<[applications count]; i++) {
 | 
			
		||||
		if ([[[applications objectAtIndex:i] objectForKey:MGMPathKey] isEqual:thePath])
 | 
			
		||||
			return YES;
 | 
			
		||||
	}
 | 
			
		||||
	return NO;
 | 
			
		||||
	return ([self itemForPath:thePath]!=nil);
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)add:(NSString *)thePath {
 | 
			
		||||
	return [self add:thePath hide:NO];
 | 
			
		||||
	return [self add:thePath hideOnLaunch:NO];
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)add:(NSString *)thePath hide:(BOOL)shouldHide {
 | 
			
		||||
- (BOOL)add:(NSString *)thePath hideOnLaunch:(BOOL)doesHide {
 | 
			
		||||
	if ([self exists:thePath])
 | 
			
		||||
		return NO;
 | 
			
		||||
	NSMutableArray *applications = [NSMutableArray arrayWithArray:[loginItems objectForKey:MGMItemsKey]];
 | 
			
		||||
	NSMutableDictionary *info = [NSMutableDictionary dictionary];
 | 
			
		||||
	[info setObject:thePath forKey:MGMPathKey];
 | 
			
		||||
	[info setObject:[NSNumber numberWithBool:shouldHide] forKey:MGMHideKey];
 | 
			
		||||
	[applications addObject:info];
 | 
			
		||||
	[loginItems setObject:applications forKey:MGMItemsKey];
 | 
			
		||||
	[self _save];
 | 
			
		||||
	if (sharedSupported) {
 | 
			
		||||
		NSMutableDictionary *itemsToSet = [NSMutableDictionary dictionary];
 | 
			
		||||
		NSMutableArray *itemsToClear = [NSMutableArray array];
 | 
			
		||||
		if (doesHide)
 | 
			
		||||
			[itemsToSet setObject:[NSNumber numberWithBool:YES] forKey:MGMLoginItemHideProperty];
 | 
			
		||||
		else
 | 
			
		||||
			[itemsToClear addObject:MGMLoginItemHideProperty];
 | 
			
		||||
		LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(itemsRef, kLSSharedFileListItemLast, NULL, NULL, (CFURLRef)[NSURL fileURLWithPath:thePath], (CFDictionaryRef)itemsToSet, (CFArrayRef)itemsToClear);
 | 
			
		||||
		MGMLoginItem *item = [MGMLoginItem itemWithItemRef:itemRef loginItems:self];
 | 
			
		||||
		CFRelease(itemRef);
 | 
			
		||||
		if (item==nil)
 | 
			
		||||
			return NO;
 | 
			
		||||
		[loginItems addObject:item];
 | 
			
		||||
		updated = YES;
 | 
			
		||||
	} else {
 | 
			
		||||
		NSDictionary *itemInfo = [NSDictionary dictionaryWithObjectsAndKeys:thePath, MGMLoginItemPathKey, [NSNumber numberWithBool:doesHide], MGMLoginItemHideKey, nil];
 | 
			
		||||
		MGMLoginItem *item = [MGMLoginItem itemWithItemInfo:itemInfo loginItems:self];
 | 
			
		||||
		if (item==nil)
 | 
			
		||||
			return NO;
 | 
			
		||||
		[loginItems addObject:item];
 | 
			
		||||
		[self saveLoginWindowItems];
 | 
			
		||||
	}
 | 
			
		||||
	return YES;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)remove:(NSString *)thePath {
 | 
			
		||||
	NSMutableArray *applications = [NSMutableArray arrayWithArray:[loginItems objectForKey:MGMItemsKey]];
 | 
			
		||||
	for (int i=0; i<[applications count]; i++) {
 | 
			
		||||
		if ([[[applications objectAtIndex:i] objectForKey:MGMPathKey] isEqual:thePath]) {
 | 
			
		||||
			[applications removeObjectAtIndex:i];
 | 
			
		||||
			[loginItems setObject:applications forKey:MGMItemsKey];
 | 
			
		||||
			[self _save];
 | 
			
		||||
			return YES;
 | 
			
		||||
	return [self removeItem:[self itemForPath:thePath]];
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)removeItem:(MGMLoginItem *)theItem {
 | 
			
		||||
	if (theItem==nil)
 | 
			
		||||
		return NO;
 | 
			
		||||
	if ([theItem type]==MGMLoginItemShared) {
 | 
			
		||||
		OSStatus result = LSSharedFileListItemRemove(itemsRef, [theItem itemRef]);
 | 
			
		||||
		if (result!=noErr) {
 | 
			
		||||
			NSLog(@"Error removing %@ %d", theItem, result);
 | 
			
		||||
			return NO;
 | 
			
		||||
		}
 | 
			
		||||
		[loginItems removeObject:theItem];
 | 
			
		||||
		updated = YES;
 | 
			
		||||
	} else {
 | 
			
		||||
		[loginItems removeObject:theItem];
 | 
			
		||||
		[self saveLoginWindowItems];
 | 
			
		||||
	}
 | 
			
		||||
	return NO;
 | 
			
		||||
	return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_save {
 | 
			
		||||
	[loginItems writeToFile:[MGMLoginItemsPath stringByExpandingTildeInPath] atomically:YES];
 | 
			
		||||
- (void)updateItems {
 | 
			
		||||
	if (updated) {
 | 
			
		||||
		updated = NO;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	[loginItems release];
 | 
			
		||||
	loginItems = [NSMutableArray new];
 | 
			
		||||
	if (sharedSupported) {
 | 
			
		||||
		UInt32 outSnapshotSeed = 0;
 | 
			
		||||
		NSArray *items = [(NSArray *)LSSharedFileListCopySnapshot(itemsRef, &outSnapshotSeed) autorelease];
 | 
			
		||||
		for (int i=0; i<[items count]; i++) {
 | 
			
		||||
			LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[items objectAtIndex:i];
 | 
			
		||||
			MGMLoginItem *item = [MGMLoginItem itemWithItemRef:itemRef loginItems:self];
 | 
			
		||||
			if (item!=nil)
 | 
			
		||||
				[loginItems addObject:item];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	NSDictionary *loginWindowItems = [NSDictionary dictionaryWithContentsOfFile:[MGMLoginItemsPath stringByExpandingTildeInPath]];
 | 
			
		||||
	NSArray *items = [loginWindowItems objectForKey:MGMLoginItemsKey];
 | 
			
		||||
	for (unsigned int i=0; i<[items count]; i++) {
 | 
			
		||||
		NSDictionary *itemInfo = [items objectAtIndex:i];
 | 
			
		||||
		if (![self exists:[itemInfo objectForKey:MGMLoginItemPathKey]]) {
 | 
			
		||||
			MGMLoginItem *item = [MGMLoginItem itemWithItemInfo:itemInfo loginItems:self];
 | 
			
		||||
			if (item!=nil)
 | 
			
		||||
				[loginItems addObject:item];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	[[NSNotificationCenter defaultCenter] postNotificationName:MGMLoginItemsUpdated object:self];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)saveLoginWindowItems {
 | 
			
		||||
	NSMutableDictionary *loginWindowItems = [NSMutableDictionary dictionaryWithContentsOfFile:[MGMLoginItemsPath stringByExpandingTildeInPath]];
 | 
			
		||||
	NSMutableArray *items = [NSMutableArray array];
 | 
			
		||||
	for (unsigned int i=0; i<[loginItems count]; i++) {
 | 
			
		||||
		MGMLoginItem *item = [loginItems objectAtIndex:i];
 | 
			
		||||
		if ([item type]==MGMLoginItemInfo) {
 | 
			
		||||
			NSDictionary *itemInfo = [NSDictionary dictionaryWithObjectsAndKeys:[item path], MGMLoginItemPathKey, [NSNumber numberWithBool:[item hideOnLaunch]], MGMLoginItemHideKey, nil];
 | 
			
		||||
			[items addObject:itemInfo];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	[loginWindowItems setObject:items forKey:MGMLoginItemsKey];
 | 
			
		||||
	[loginWindowItems writeToFile:[MGMLoginItemsPath stringByExpandingTildeInPath] atomically:YES];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)subscribedPathChanged:(NSString *)thePath {
 | 
			
		||||
	[self updateItems];
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
@ -53,7 +53,7 @@
 | 
			
		||||
		[path fill];
 | 
			
		||||
		displayImage = alternateImage;
 | 
			
		||||
	}
 | 
			
		||||
	[displayImage drawInRect:NSMakeRect((22-[image size].width)/2, (22-[image size].height)/2, [image size].width, [image size].height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
 | 
			
		||||
	[displayImage drawInRect:NSMakeRect(3, 3, 16, 16) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)mouseDown:(NSEvent *)theEvent {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMPathSubscriber.h
 | 
			
		||||
//  CocoaShare
 | 
			
		||||
//  Conmote
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 1/15/11.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,20 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMPathSubscriber.m
 | 
			
		||||
//  CocoaShare
 | 
			
		||||
//  Conmote
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 1/15/11.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//  Created by Mr. Gecko on 8/14/13.
 | 
			
		||||
//  Copyright (c) 2013 Mr. Gecko's Media (James Coleman). http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
//  Permission to use, copy, modify, and/or distribute this software for any purpose
 | 
			
		||||
//  with or without fee is hereby granted, provided that the above copyright notice
 | 
			
		||||
//  and this permission notice appear in all copies.
 | 
			
		||||
//
 | 
			
		||||
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 | 
			
		||||
//  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
//  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
 | 
			
		||||
//  OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
			
		||||
//  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 | 
			
		||||
//  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MGMPathSubscriber.h"
 | 
			
		||||
@ -28,7 +39,7 @@
 | 
			
		||||
		fileDescriptor = open([path fileSystemRepresentation], O_EVTONLY, 0);
 | 
			
		||||
		if (fileDescriptor<0) {
 | 
			
		||||
			[self release];
 | 
			
		||||
			self = nil;
 | 
			
		||||
			return nil;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
@ -121,21 +132,6 @@ void MGMPathSubscriptionFSChange(ConstFSEventStreamRef streamRef, void *thePathS
 | 
			
		||||
	delegate = theDelegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (int)OSMajorVersion {
 | 
			
		||||
	SInt32 majorVersion;
 | 
			
		||||
	if (Gestalt(gestaltSystemVersionMajor, &majorVersion)==noErr) {
 | 
			
		||||
		return (int)majorVersion;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
- (int)OSMinorVersion {
 | 
			
		||||
	SInt32 minorVersion;
 | 
			
		||||
	if (Gestalt(gestaltSystemVersionMinor, &minorVersion)==noErr) {
 | 
			
		||||
		return (int)minorVersion;
 | 
			
		||||
	}
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)addPath:(NSString *)thePath {
 | 
			
		||||
	[self addPath:thePath fileOptions:MGMFODelete | MGMFOWrite | MGMFOExtend | MGMFOAttribute | MGMFOLink | MGMFORename | MGMFORevoke];
 | 
			
		||||
}
 | 
			
		||||
@ -151,9 +147,9 @@ void MGMPathSubscriptionFSChange(ConstFSEventStreamRef streamRef, void *thePathS
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (directory) {
 | 
			
		||||
		if ([self OSMajorVersion]==10 && [self OSMinorVersion]>=5) {
 | 
			
		||||
		if (NSFoundationVersionNumber>=677.00/*NSFoundationVersionNumber10_5*/) {
 | 
			
		||||
			FSEventStreamContext context = {0, self, NULL, NULL, NULL};
 | 
			
		||||
			FSEventStreamRef stream = FSEventStreamCreate(NULL, &MGMPathSubscriptionFSChange, &context, (CFArrayRef)[NSArray arrayWithObject:thePath], kFSEventStreamEventIdSinceNow, 0.5, kFSEventStreamCreateFlagNone);
 | 
			
		||||
			FSEventStreamRef stream = FSEventStreamCreate(NULL, &MGMPathSubscriptionFSChange, &context, (CFArrayRef)[NSArray arrayWithObject:thePath], kFSEventStreamEventIdSinceNow, 0.5, kFSEventStreamCreateFlagFileEvents);
 | 
			
		||||
			if (stream==NULL) {
 | 
			
		||||
				NSLog(@"MGMPathSubscription: Unable to subscribe to %@", thePath);
 | 
			
		||||
				return;
 | 
			
		||||
@ -195,7 +191,7 @@ void MGMPathSubscriptionFSChange(ConstFSEventStreamRef streamRef, void *thePathS
 | 
			
		||||
	NSValue *value = [subscriptions objectForKey:thePath];
 | 
			
		||||
	if (value!=nil) {
 | 
			
		||||
		if ([value isKindOfClass:[NSValue class]]) {
 | 
			
		||||
			if ([self OSMajorVersion]==10 && [self OSMinorVersion]>=5) {
 | 
			
		||||
			if (NSFoundationVersionNumber>=677.00/*NSFoundationVersionNumber10_5*/) {
 | 
			
		||||
				FSEventStreamRef stream = [value pointerValue];
 | 
			
		||||
				FSEventStreamStop(stream);
 | 
			
		||||
				FSEventStreamUnscheduleFromRunLoop(stream, runLoop, kCFRunLoopDefaultMode);
 | 
			
		||||
@ -216,7 +212,7 @@ void MGMPathSubscriptionFSChange(ConstFSEventStreamRef streamRef, void *thePathS
 | 
			
		||||
	for (int i=0; i<[keys count]; i++) {
 | 
			
		||||
		NSValue *value = [subscriptions objectForKey:[keys objectAtIndex:i]];
 | 
			
		||||
		if ([value isKindOfClass:[NSValue class]]) {
 | 
			
		||||
			if ([self OSMajorVersion]==10 && [self OSMinorVersion]>=5) {
 | 
			
		||||
			if (NSFoundationVersionNumber>=677.00/*NSFoundationVersionNumber10_5*/) {
 | 
			
		||||
				FSEventStreamRef stream = [value pointerValue];
 | 
			
		||||
				FSEventStreamStop(stream);
 | 
			
		||||
				FSEventStreamUnscheduleFromRunLoop(stream, runLoop, kCFRunLoopDefaultMode);
 | 
			
		||||
 | 
			
		||||
@ -122,6 +122,8 @@
 | 
			
		||||
		[sound setDelegate:self];
 | 
			
		||||
		[sound play];
 | 
			
		||||
		[preferences setObject:[[soundPopUp selectedItem] representedObject] forKey:[NSString stringWithFormat:MGMESound, [eventPopUp indexOfSelectedItem]]];
 | 
			
		||||
	} else {
 | 
			
		||||
		[preferences removeObjectForKey:[NSString stringWithFormat:MGMESound, [eventPopUp indexOfSelectedItem]]];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
- (void)sound:(NSSound *)theSound didFinishPlaying:(BOOL)finishedPlaying {
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBAccountInfo.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#import "DBQuota.h"
 | 
			
		||||
 | 
			
		||||
@interface DBAccountInfo : NSObject <NSCoding> {
 | 
			
		||||
    NSString* country;
 | 
			
		||||
    NSString* displayName;
 | 
			
		||||
    DBQuota* quota;
 | 
			
		||||
    NSString* userId;
 | 
			
		||||
    NSString* referralLink;
 | 
			
		||||
}
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict;
 | 
			
		||||
 | 
			
		||||
- (NSString *)country;
 | 
			
		||||
- (NSString *)displayName;
 | 
			
		||||
- (DBQuota *)quota;
 | 
			
		||||
- (NSString *)userId;
 | 
			
		||||
- (NSString *)referralLink;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,70 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBAccountInfo.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBAccountInfo.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation DBAccountInfo
 | 
			
		||||
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        country = [[dict objectForKey:@"country"] retain];
 | 
			
		||||
        displayName = [[dict objectForKey:@"display_name"] retain];
 | 
			
		||||
        quota = [[DBQuota alloc] initWithDictionary:[dict objectForKey:@"quota_info"]];
 | 
			
		||||
        userId = [[[dict objectForKey:@"uid"] stringValue] retain];
 | 
			
		||||
        referralLink = [[dict objectForKey:@"referral_link"] retain];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [country release];
 | 
			
		||||
    [displayName release];
 | 
			
		||||
    [quota release];
 | 
			
		||||
    [userId release];
 | 
			
		||||
    [referralLink release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)country {
 | 
			
		||||
	return country;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)displayName {
 | 
			
		||||
	return displayName;
 | 
			
		||||
}
 | 
			
		||||
- (DBQuota *)quota {
 | 
			
		||||
	return quota;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)userId {
 | 
			
		||||
	return userId;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)referralLink {
 | 
			
		||||
	return referralLink;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark NSCoding methods
 | 
			
		||||
 | 
			
		||||
- (void)encodeWithCoder:(NSCoder*)coder {
 | 
			
		||||
    [coder encodeObject:country forKey:@"country"];
 | 
			
		||||
    [coder encodeObject:displayName forKey:@"displayName"];
 | 
			
		||||
    [coder encodeObject:quota forKey:@"quota"];
 | 
			
		||||
    [coder encodeObject:userId forKey:@"userId"];
 | 
			
		||||
    [coder encodeObject:referralLink forKey:@"referralLink"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCoder:(NSCoder*)coder {
 | 
			
		||||
    self = [super init];
 | 
			
		||||
    country = [[coder decodeObjectForKey:@"country"] retain];
 | 
			
		||||
    displayName = [[coder decodeObjectForKey:@"displayName"] retain];
 | 
			
		||||
    quota = [[coder decodeObjectForKey:@"quota"] retain];
 | 
			
		||||
    userId = [[coder decodeObjectForKey:@"userId"] retain];
 | 
			
		||||
    referralLink = [[coder decodeObjectForKey:@"referralLink"] retain];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBError.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 7/21/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
/* This file contains error codes and the dropbox error domain */
 | 
			
		||||
 | 
			
		||||
extern NSString* DBErrorDomain;
 | 
			
		||||
 | 
			
		||||
// Error codes in the dropbox.com domain represent the HTTP status code if less than 1000
 | 
			
		||||
typedef enum {
 | 
			
		||||
    DBErrorNone = 0,
 | 
			
		||||
    DBErrorGenericError = 1000,
 | 
			
		||||
    DBErrorFileNotFound,
 | 
			
		||||
    DBErrorInsufficientDiskSpace,
 | 
			
		||||
} DBErrorCode;
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBError.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 7/21/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBError.h"
 | 
			
		||||
 | 
			
		||||
NSString* DBErrorDomain = @"dropbox.com";
 | 
			
		||||
@ -1,38 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBMetadata.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface DBMetadata : NSObject <NSCoding> {
 | 
			
		||||
    BOOL thumbnailExists;
 | 
			
		||||
    long long totalBytes;
 | 
			
		||||
    NSDate* lastModifiedDate;
 | 
			
		||||
    NSString* path;
 | 
			
		||||
    BOOL isDirectory;
 | 
			
		||||
    NSArray* contents;
 | 
			
		||||
    NSString* hash;
 | 
			
		||||
    NSString* humanReadableSize;
 | 
			
		||||
    NSString* root;
 | 
			
		||||
    NSString* icon;
 | 
			
		||||
    long long revision;
 | 
			
		||||
    BOOL isDeleted;
 | 
			
		||||
}
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict;
 | 
			
		||||
 | 
			
		||||
- (BOOL)thumbnailExists;
 | 
			
		||||
- (long long)totalBytes;
 | 
			
		||||
- (NSDate *)lastModifiedDate;
 | 
			
		||||
- (NSString *)path;
 | 
			
		||||
- (BOOL)isDirectory;
 | 
			
		||||
- (NSArray *)contents;
 | 
			
		||||
- (NSString *)hash;
 | 
			
		||||
- (NSString *)humanReadableSize;
 | 
			
		||||
- (NSString *)root;
 | 
			
		||||
- (NSString *)icon;
 | 
			
		||||
- (long long)revision;
 | 
			
		||||
- (BOOL)isDeleted;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,150 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBMetadata.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBMetadata.h"
 | 
			
		||||
 | 
			
		||||
@implementation DBMetadata
 | 
			
		||||
 | 
			
		||||
+ (NSDateFormatter*)dateFormatter {
 | 
			
		||||
	NSMutableDictionary* dictionary = [[NSThread currentThread] threadDictionary];
 | 
			
		||||
	static NSString* dateFormatterKey = @"DBMetadataDateFormatter";
 | 
			
		||||
	
 | 
			
		||||
    NSDateFormatter* dateFormatter = [dictionary objectForKey:dateFormatterKey];
 | 
			
		||||
    if (dateFormatter == nil) {
 | 
			
		||||
        dateFormatter = [[NSDateFormatter new] autorelease];
 | 
			
		||||
        // Must set locale to ensure consistent parsing:
 | 
			
		||||
        // http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html
 | 
			
		||||
		dateFormatter.locale = 
 | 
			
		||||
			[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
 | 
			
		||||
		dateFormatter.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss Z";
 | 
			
		||||
        [dictionary setObject:dateFormatter forKey:dateFormatterKey];
 | 
			
		||||
    }
 | 
			
		||||
    return dateFormatter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        thumbnailExists = [[dict objectForKey:@"thumb_exists"] boolValue];
 | 
			
		||||
        totalBytes = [[dict objectForKey:@"bytes"] longLongValue];
 | 
			
		||||
 | 
			
		||||
        if ([dict objectForKey:@"modified"]) {
 | 
			
		||||
            lastModifiedDate = 
 | 
			
		||||
				[[[DBMetadata dateFormatter] dateFromString:[dict objectForKey:@"modified"]] retain];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        path = [[dict objectForKey:@"path"] retain];
 | 
			
		||||
        isDirectory = [[dict objectForKey:@"is_dir"] boolValue];
 | 
			
		||||
        
 | 
			
		||||
        if ([dict objectForKey:@"contents"]) {
 | 
			
		||||
            NSArray* subfileDicts = [dict objectForKey:@"contents"];
 | 
			
		||||
            NSMutableArray* mutableContents = 
 | 
			
		||||
                [[NSMutableArray alloc] initWithCapacity:[subfileDicts count]];
 | 
			
		||||
            for (long long i=0; i<[subfileDicts count]; i++) {
 | 
			
		||||
                DBMetadata* subfile = [[DBMetadata alloc] initWithDictionary:[subfileDicts objectAtIndex:i]];
 | 
			
		||||
                [mutableContents addObject:subfile];
 | 
			
		||||
                [subfile release];
 | 
			
		||||
            }
 | 
			
		||||
            contents = mutableContents;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        hash = [[dict objectForKey:@"hash"] retain];
 | 
			
		||||
        humanReadableSize = [[dict objectForKey:@"size"] retain];
 | 
			
		||||
        root = [[dict objectForKey:@"root"] retain];
 | 
			
		||||
        icon = [[dict objectForKey:@"icon"] retain];
 | 
			
		||||
        revision = [[dict objectForKey:@"revision"] longLongValue];
 | 
			
		||||
        isDeleted = [[dict objectForKey:@"is_deleted"] boolValue];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [lastModifiedDate release];
 | 
			
		||||
    [path release];
 | 
			
		||||
    [contents release];
 | 
			
		||||
    [hash release];
 | 
			
		||||
    [humanReadableSize release];
 | 
			
		||||
    [root release];
 | 
			
		||||
    [icon release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)thumbnailExists {
 | 
			
		||||
	return thumbnailExists;
 | 
			
		||||
}
 | 
			
		||||
- (long long)totalBytes {
 | 
			
		||||
	return totalBytes;
 | 
			
		||||
}
 | 
			
		||||
- (NSDate *)lastModifiedDate {
 | 
			
		||||
	return lastModifiedDate;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)path {
 | 
			
		||||
	return path;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)isDirectory {
 | 
			
		||||
	return isDirectory;
 | 
			
		||||
}
 | 
			
		||||
- (NSArray *)contents {
 | 
			
		||||
	return contents;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)hash {
 | 
			
		||||
	return hash;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)humanReadableSize {
 | 
			
		||||
	return humanReadableSize;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)root {
 | 
			
		||||
	return root;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)icon {
 | 
			
		||||
	return icon;
 | 
			
		||||
}
 | 
			
		||||
- (long long)revision {
 | 
			
		||||
	return revision;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)isDeleted {
 | 
			
		||||
	return isDeleted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma mark NSCoding methods
 | 
			
		||||
 | 
			
		||||
- (id)initWithCoder:(NSCoder*)coder {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        thumbnailExists = [coder decodeBoolForKey:@"thumbnailExists"];
 | 
			
		||||
        totalBytes = [coder decodeInt64ForKey:@"totalBytes"];
 | 
			
		||||
        lastModifiedDate = [[coder decodeObjectForKey:@"lastModifiedDate"] retain];
 | 
			
		||||
        path = [[coder decodeObjectForKey:@"path"] retain];
 | 
			
		||||
        isDirectory = [coder decodeBoolForKey:@"isDirectory"];
 | 
			
		||||
        contents = [[coder decodeObjectForKey:@"contents"] retain];
 | 
			
		||||
        hash = [[coder decodeObjectForKey:@"hash"] retain];
 | 
			
		||||
        humanReadableSize = [[coder decodeObjectForKey:@"humanReadableSize"] retain];
 | 
			
		||||
        root = [[coder decodeObjectForKey:@"root"] retain];
 | 
			
		||||
        icon = [[coder decodeObjectForKey:@"icon"] retain];
 | 
			
		||||
        revision = [coder decodeInt64ForKey:@"revision"];
 | 
			
		||||
        isDeleted = [coder decodeBoolForKey:@"isDeleted"];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)encodeWithCoder:(NSCoder*)coder {
 | 
			
		||||
    [coder encodeBool:thumbnailExists forKey:@"thumbnailExists"];
 | 
			
		||||
    [coder encodeInt64:totalBytes forKey:@"totalBytes"];
 | 
			
		||||
    [coder encodeObject:lastModifiedDate forKey:@"lastModifiedDate"];
 | 
			
		||||
    [coder encodeObject:path forKey:@"path"];
 | 
			
		||||
    [coder encodeBool:isDirectory forKey:@"isDirectory"];
 | 
			
		||||
    [coder encodeObject:contents forKey:@"contents"];
 | 
			
		||||
    [coder encodeObject:hash forKey:@"hash"];
 | 
			
		||||
    [coder encodeObject:humanReadableSize forKey:@"humanReadableSize"];
 | 
			
		||||
    [coder encodeObject:root forKey:@"root"];
 | 
			
		||||
    [coder encodeObject:icon forKey:@"icon"];
 | 
			
		||||
    [coder encodeInt64:revision forKey:@"revision"];
 | 
			
		||||
    [coder encodeBool:isDeleted forKey:@"isDeleted"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBQuota.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface DBQuota : NSObject <NSCoding> {
 | 
			
		||||
    long long normalConsumedBytes;
 | 
			
		||||
    long long sharedConsumedBytes;
 | 
			
		||||
    long long totalBytes;
 | 
			
		||||
}
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict;
 | 
			
		||||
 | 
			
		||||
- (long long)normalConsumedBytes;
 | 
			
		||||
- (long long)sharedConsumedBytes;
 | 
			
		||||
- (long long)totalConsumedBytes;
 | 
			
		||||
- (long long)totalBytes;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,56 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBQuotaInfo.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 5/3/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBQuota.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation DBQuota
 | 
			
		||||
 | 
			
		||||
- (id)initWithDictionary:(NSDictionary*)dict {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        normalConsumedBytes = [[dict objectForKey:@"normal"] longLongValue];
 | 
			
		||||
        sharedConsumedBytes = [[dict objectForKey:@"shared"] longLongValue];
 | 
			
		||||
        totalBytes = [[dict objectForKey:@"quota"] longLongValue];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (long long)normalConsumedBytes {
 | 
			
		||||
	return normalConsumedBytes;
 | 
			
		||||
}
 | 
			
		||||
- (long long)sharedConsumedBytes {
 | 
			
		||||
	return sharedConsumedBytes;
 | 
			
		||||
}
 | 
			
		||||
- (long long)totalConsumedBytes {
 | 
			
		||||
	return normalConsumedBytes + sharedConsumedBytes;
 | 
			
		||||
}
 | 
			
		||||
- (long long)totalBytes {
 | 
			
		||||
	return totalBytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark NSCoding methods
 | 
			
		||||
 | 
			
		||||
- (void)encodeWithCoder:(NSCoder*)coder {
 | 
			
		||||
    [coder encodeInt64:normalConsumedBytes forKey:@"normalConsumedBytes"];
 | 
			
		||||
    [coder encodeInt64:sharedConsumedBytes forKey:@"sharedConsumedBytes"];
 | 
			
		||||
    [coder encodeInt64:totalBytes forKey:@"totalBytes"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCoder:(NSCoder*)coder {
 | 
			
		||||
    self = [super init];
 | 
			
		||||
    normalConsumedBytes = [coder decodeInt64ForKey:@"normalConsumedBytes"];
 | 
			
		||||
    sharedConsumedBytes = [coder decodeInt64ForKey:@"sharedConsumedBytes"];
 | 
			
		||||
    totalBytes = [coder decodeInt64ForKey:@"totalBytes"];
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,75 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBRestRequest.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/9/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@protocol DBNetworkRequestDelegate;
 | 
			
		||||
 | 
			
		||||
/* DBRestRequest will download a URL either into a file that you provied the name to or it will
 | 
			
		||||
   create an NSData object with the result. When it has completed downloading the URL, it will
 | 
			
		||||
   notify the target with a selector that takes the DBRestRequest as the only parameter. */
 | 
			
		||||
@interface DBRequest : NSObject {
 | 
			
		||||
    NSURLRequest* request;
 | 
			
		||||
    id target;
 | 
			
		||||
    SEL selector;
 | 
			
		||||
    NSURLConnection* urlConnection;
 | 
			
		||||
    NSFileHandle* fileHandle;
 | 
			
		||||
 | 
			
		||||
    SEL failureSelector;
 | 
			
		||||
    SEL downloadProgressSelector;
 | 
			
		||||
    SEL uploadProgressSelector;
 | 
			
		||||
    NSString* resultFilename;
 | 
			
		||||
    NSString* tempFilename;
 | 
			
		||||
    NSDictionary* userInfo;
 | 
			
		||||
 | 
			
		||||
    NSHTTPURLResponse* response;
 | 
			
		||||
    int bytesDownloaded;
 | 
			
		||||
    float downloadProgress;
 | 
			
		||||
    float uploadProgress;
 | 
			
		||||
    NSMutableData* resultData;
 | 
			
		||||
    NSError* error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*  Set this to get called when _any_ request starts or stops. This should hook into whatever
 | 
			
		||||
    network activity indicator system you have. */
 | 
			
		||||
+ (void)setNetworkRequestDelegate:(id<DBNetworkRequestDelegate>)delegate;
 | 
			
		||||
 | 
			
		||||
/*  This constructor downloads the URL into the resultData object */
 | 
			
		||||
- (id)initWithURLRequest:(NSURLRequest*)request andInformTarget:(id)target selector:(SEL)selector;
 | 
			
		||||
 | 
			
		||||
/*  Cancels the request and prevents it from sending additional messages to the delegate. */
 | 
			
		||||
- (void)cancel;
 | 
			
		||||
 | 
			
		||||
- (void)setFailureSelector:(SEL)theSelector; // To send failure events to a different selector set this
 | 
			
		||||
- (SEL)failureSelector;
 | 
			
		||||
- (void)setDownloadProgressSelector:(SEL)theSelector; // To receive download progress events set this
 | 
			
		||||
- (SEL)downloadProgressSelector;
 | 
			
		||||
- (void)setUploadProgressSelector:(SEL)theSelector; // To receive upload progress events set this
 | 
			
		||||
- (SEL)uploadProgressSelector;
 | 
			
		||||
- (void)setResultFilename:(NSString *)theName; // The file to put the HTTP body in, otherwise body is stored in resultData
 | 
			
		||||
- (NSString *)resultFilename;
 | 
			
		||||
- (void)setUserInfo:(NSDictionary *)theInfo;
 | 
			
		||||
- (NSDictionary *)userInfo;
 | 
			
		||||
 | 
			
		||||
- (NSURLRequest *)request;
 | 
			
		||||
- (NSHTTPURLResponse *)response;
 | 
			
		||||
- (int)statusCode;
 | 
			
		||||
- (float)downloadProgress;
 | 
			
		||||
- (float)uploadProgress;
 | 
			
		||||
- (NSData *)resultData;
 | 
			
		||||
- (NSString *)resultString;
 | 
			
		||||
- (NSObject *)resultJSON;
 | 
			
		||||
- (NSError *)error;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@protocol DBNetworkRequestDelegate 
 | 
			
		||||
 | 
			
		||||
- (void)networkRequestStarted;
 | 
			
		||||
- (void)networkRequestStopped;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,283 +0,0 @@
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 | 
			
		||||
//
 | 
			
		||||
//  DBRestRequest.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/9/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBRequest.h"
 | 
			
		||||
#import "DBError.h"
 | 
			
		||||
#import "JSON.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static id networkRequestDelegate = nil;
 | 
			
		||||
 | 
			
		||||
@implementation DBRequest
 | 
			
		||||
 | 
			
		||||
+ (void)setNetworkRequestDelegate:(id<DBNetworkRequestDelegate>)delegate {
 | 
			
		||||
    networkRequestDelegate = delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithURLRequest:(NSURLRequest*)aRequest andInformTarget:(id)aTarget selector:(SEL)aSelector {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        request = [aRequest retain];
 | 
			
		||||
        target = aTarget;
 | 
			
		||||
        selector = aSelector;
 | 
			
		||||
        
 | 
			
		||||
        urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
 | 
			
		||||
        [networkRequestDelegate networkRequestStarted];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void) dealloc {
 | 
			
		||||
    [urlConnection cancel];
 | 
			
		||||
	
 | 
			
		||||
    [request release];
 | 
			
		||||
    [urlConnection release];
 | 
			
		||||
    [fileHandle release];
 | 
			
		||||
    [userInfo release];
 | 
			
		||||
    [response release];
 | 
			
		||||
    [resultFilename release];
 | 
			
		||||
    [tempFilename release];
 | 
			
		||||
    [resultData release];
 | 
			
		||||
    [error release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setFailureSelector:(SEL)theSelector {
 | 
			
		||||
	failureSelector = theSelector;
 | 
			
		||||
}
 | 
			
		||||
- (SEL)failureSelector {
 | 
			
		||||
	return failureSelector;
 | 
			
		||||
}
 | 
			
		||||
- (void)setDownloadProgressSelector:(SEL)theSelector {
 | 
			
		||||
	downloadProgressSelector = theSelector;
 | 
			
		||||
}
 | 
			
		||||
- (SEL)downloadProgressSelector {
 | 
			
		||||
	return downloadProgressSelector;
 | 
			
		||||
}
 | 
			
		||||
- (void)setUploadProgressSelector:(SEL)theSelector {
 | 
			
		||||
	uploadProgressSelector = theSelector;
 | 
			
		||||
}
 | 
			
		||||
- (SEL)uploadProgressSelector {
 | 
			
		||||
	return uploadProgressSelector;
 | 
			
		||||
}
 | 
			
		||||
- (void)setResultFilename:(NSString *)theName {
 | 
			
		||||
	[resultFilename release];
 | 
			
		||||
	resultFilename = [theName retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)resultFilename {
 | 
			
		||||
	return resultFilename;
 | 
			
		||||
}
 | 
			
		||||
- (void)setUserInfo:(NSDictionary *)theInfo {
 | 
			
		||||
	[userInfo release];
 | 
			
		||||
	userInfo = [theInfo retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSDictionary *)userInfo {
 | 
			
		||||
	return userInfo;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSURLRequest *)request {
 | 
			
		||||
	return request;
 | 
			
		||||
}
 | 
			
		||||
- (NSHTTPURLResponse *)response {
 | 
			
		||||
	return response;
 | 
			
		||||
}
 | 
			
		||||
- (int)statusCode {
 | 
			
		||||
	return [response statusCode];
 | 
			
		||||
}
 | 
			
		||||
- (float)downloadProgress {
 | 
			
		||||
	return downloadProgress;
 | 
			
		||||
}
 | 
			
		||||
- (float)uploadProgress {
 | 
			
		||||
	return uploadProgress;
 | 
			
		||||
}
 | 
			
		||||
- (NSData *)resultData {
 | 
			
		||||
	return resultData;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)resultString {
 | 
			
		||||
	return [[[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
}
 | 
			
		||||
- (NSObject *)resultJSON {
 | 
			
		||||
	return [[self resultString] JSONValue];
 | 
			
		||||
}
 | 
			
		||||
- (NSError *)error {
 | 
			
		||||
	return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)cancel {
 | 
			
		||||
    [urlConnection cancel];
 | 
			
		||||
    target = nil;
 | 
			
		||||
    
 | 
			
		||||
    if (tempFilename) {
 | 
			
		||||
        [fileHandle closeFile];
 | 
			
		||||
        NSError *rmError = nil;
 | 
			
		||||
		NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
		BOOL result = NO;
 | 
			
		||||
		if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
			result = [manager removeFileAtPath:tempFilename handler:nil];
 | 
			
		||||
		else
 | 
			
		||||
			result = [manager removeItemAtPath:tempFilename error:&rmError];
 | 
			
		||||
        if (!result)
 | 
			
		||||
            NSLog(@"DBRequest#cancel Error removing temp file: %@", rmError);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    [networkRequestDelegate networkRequestStopped];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark NSURLConnection delegate methods
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)aResponse {
 | 
			
		||||
    response = [(NSHTTPURLResponse*)aResponse retain];
 | 
			
		||||
    
 | 
			
		||||
    if (resultFilename && [self statusCode] == 200) {
 | 
			
		||||
        // Create the file here so it's created in case it's zero length
 | 
			
		||||
        // File is downloaded into a temporary file and then moved over when completed successfully
 | 
			
		||||
        NSString* filename = 
 | 
			
		||||
            [NSString stringWithFormat:@"%.0f", 1000*[NSDate timeIntervalSinceReferenceDate]];
 | 
			
		||||
        tempFilename = [[NSTemporaryDirectory() stringByAppendingPathComponent:filename] retain];
 | 
			
		||||
        
 | 
			
		||||
        NSFileManager* fileManager = [[NSFileManager new] autorelease];
 | 
			
		||||
        BOOL success = [fileManager createFileAtPath:tempFilename contents:nil attributes:nil];
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            NSLog(@"DBRequest#connection:didReceiveData: Error creating file at path: %@", 
 | 
			
		||||
                    tempFilename);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fileHandle = [[NSFileHandle fileHandleForWritingAtPath:tempFilename] retain];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
 | 
			
		||||
    if (resultFilename && [self statusCode] == 200) {
 | 
			
		||||
        @try {
 | 
			
		||||
            [fileHandle writeData:data];
 | 
			
		||||
        } @catch (NSException* e) {
 | 
			
		||||
            // In case we run out of disk space
 | 
			
		||||
            [urlConnection cancel];
 | 
			
		||||
            [fileHandle closeFile];
 | 
			
		||||
			NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
			if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
				[manager removeFileAtPath:tempFilename handler:nil];
 | 
			
		||||
			else
 | 
			
		||||
				[manager removeItemAtPath:tempFilename error:nil];
 | 
			
		||||
            error = [[NSError alloc] initWithDomain:DBErrorDomain
 | 
			
		||||
                                        code:DBErrorInsufficientDiskSpace userInfo:userInfo];
 | 
			
		||||
            
 | 
			
		||||
            SEL sel = failureSelector ? failureSelector : selector;
 | 
			
		||||
            [target performSelector:sel withObject:self];
 | 
			
		||||
            
 | 
			
		||||
            [networkRequestDelegate networkRequestStopped];
 | 
			
		||||
            
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (resultData == nil) {
 | 
			
		||||
            resultData = [NSMutableData new];
 | 
			
		||||
        }
 | 
			
		||||
        [resultData appendData:data];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bytesDownloaded += [data length];
 | 
			
		||||
    int contentLength = [[[response allHeaderFields] objectForKey:@"Content-Length"] intValue];
 | 
			
		||||
    downloadProgress = (float)bytesDownloaded / (float)contentLength;
 | 
			
		||||
    if (downloadProgressSelector) {
 | 
			
		||||
        [target performSelector:downloadProgressSelector withObject:self];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
 | 
			
		||||
    [fileHandle closeFile];
 | 
			
		||||
    [fileHandle release];
 | 
			
		||||
    fileHandle = nil;
 | 
			
		||||
    
 | 
			
		||||
    if ([self statusCode] != 200) {
 | 
			
		||||
        NSMutableDictionary* errorUserInfo = [NSMutableDictionary dictionaryWithDictionary:userInfo];
 | 
			
		||||
        // To get error userInfo, first try and make sense of the response as JSON, if that
 | 
			
		||||
        // fails then send back the string as an error message
 | 
			
		||||
        NSString* resultString = [self resultString];
 | 
			
		||||
        if ([resultString length] > 0) {
 | 
			
		||||
            @try {
 | 
			
		||||
                SBJsonParser *jsonParser = [SBJsonParser new];
 | 
			
		||||
                NSObject* resultJSON = [jsonParser objectWithString:resultString];
 | 
			
		||||
                [jsonParser release];
 | 
			
		||||
                
 | 
			
		||||
                if ([resultJSON isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
                    [errorUserInfo addEntriesFromDictionary:(NSDictionary*)resultJSON];
 | 
			
		||||
                }
 | 
			
		||||
            } @catch (NSException* e) {
 | 
			
		||||
                [errorUserInfo setObject:resultString forKey:@"errorMessage"];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        error = [[NSError alloc] initWithDomain:@"dropbox.com" code:[self statusCode] userInfo:errorUserInfo];
 | 
			
		||||
    } else if (tempFilename) {
 | 
			
		||||
        // Move temp file over to desired file
 | 
			
		||||
        NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
		if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
			[manager removeFileAtPath:resultFilename handler:nil];
 | 
			
		||||
		else
 | 
			
		||||
			[manager removeItemAtPath:resultFilename error:nil];
 | 
			
		||||
        NSError* moveError;
 | 
			
		||||
		BOOL result = NO;
 | 
			
		||||
		if ([manager respondsToSelector:@selector(movePath:toPath:handler:)])
 | 
			
		||||
			result = [manager movePath:tempFilename toPath:resultFilename handler:nil];
 | 
			
		||||
		else
 | 
			
		||||
			result = [manager moveItemAtPath:tempFilename toPath:resultFilename error:&moveError];
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            NSLog(@"DBRequest#connectionDidFinishLoading: error moving temp file to desired location: %@",
 | 
			
		||||
                [moveError localizedDescription]);
 | 
			
		||||
            error = [[NSError alloc] initWithDomain:moveError.domain code:moveError.code userInfo:userInfo];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [tempFilename release];
 | 
			
		||||
        tempFilename = nil;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    SEL sel = (error && failureSelector) ? failureSelector : selector;
 | 
			
		||||
    [target performSelector:sel withObject:self];
 | 
			
		||||
    
 | 
			
		||||
    [networkRequestDelegate networkRequestStopped];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)anError {
 | 
			
		||||
    [fileHandle closeFile];
 | 
			
		||||
    error = [[NSError alloc] initWithDomain:anError.domain code:anError.code userInfo:userInfo];
 | 
			
		||||
    bytesDownloaded = 0;
 | 
			
		||||
    downloadProgress = 0;
 | 
			
		||||
    uploadProgress = 0;
 | 
			
		||||
    
 | 
			
		||||
    if (tempFilename) {
 | 
			
		||||
        NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
		NSError *removeError = nil;
 | 
			
		||||
		BOOL result = NO;
 | 
			
		||||
		if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
			result = [manager removeFileAtPath:tempFilename handler:nil];
 | 
			
		||||
		else
 | 
			
		||||
			result = [manager removeItemAtPath:tempFilename error:&removeError];
 | 
			
		||||
        if (!result)
 | 
			
		||||
            NSLog(@"DBRequest#connection:didFailWithError: error removing temporary file: %@", 
 | 
			
		||||
                    [removeError localizedDescription]);
 | 
			
		||||
        [tempFilename release];
 | 
			
		||||
        tempFilename = nil;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    SEL sel = failureSelector ? failureSelector : selector;
 | 
			
		||||
    [target performSelector:sel withObject:self];
 | 
			
		||||
 | 
			
		||||
    [networkRequestDelegate networkRequestStopped];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten 
 | 
			
		||||
    totalBytesWritten:(NSInteger)totalBytesWritten 
 | 
			
		||||
    totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
 | 
			
		||||
    
 | 
			
		||||
    uploadProgress = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
 | 
			
		||||
    if (uploadProgressSelector) {
 | 
			
		||||
        [target performSelector:uploadProgressSelector withObject:self];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,138 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBRestClient.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/9/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#import "DBSession.h"
 | 
			
		||||
 | 
			
		||||
@protocol DBRestClientDelegate;
 | 
			
		||||
@class DBAccountInfo;
 | 
			
		||||
@class DBMetadata;
 | 
			
		||||
 | 
			
		||||
extern NSString* kDBProtocolHTTP;
 | 
			
		||||
extern NSString* kDBProtocolHTTPS;
 | 
			
		||||
 | 
			
		||||
@interface DBRestClient : NSObject {
 | 
			
		||||
    DBSession* session;
 | 
			
		||||
    NSString* root;
 | 
			
		||||
    NSMutableSet* requests;
 | 
			
		||||
    /* Map from path to the load request. Needs to be expanded to a general framework for cancelling
 | 
			
		||||
       requests. */
 | 
			
		||||
    NSMutableDictionary* loadRequests; 
 | 
			
		||||
    id<DBRestClientDelegate> delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithSession:(DBSession*)session;
 | 
			
		||||
 | 
			
		||||
/* New developers should not use this method, and instead just use initWithSession: */
 | 
			
		||||
- (id)initWithSession:(DBSession *)session root:(NSString*)root;
 | 
			
		||||
 | 
			
		||||
/* Logs in as the user with the given email/password and stores the OAuth tokens on the session 
 | 
			
		||||
   object */
 | 
			
		||||
- (void)loginWithEmail:(NSString*)email password:(NSString*)password;
 | 
			
		||||
 | 
			
		||||
/* Loads metadata for the object at the given root/path and returns the result to the delegate as a 
 | 
			
		||||
   dictionary */
 | 
			
		||||
- (void)loadMetadata:(NSString*)path withHash:(NSString*)hash;
 | 
			
		||||
- (void)loadMetadata:(NSString*)path;
 | 
			
		||||
 | 
			
		||||
/* Loads the file contents at the given root/path and stores the result into destinationPath */
 | 
			
		||||
- (void)loadFile:(NSString *)path intoPath:(NSString *)destinationPath;
 | 
			
		||||
- (void)cancelFileLoad:(NSString*)path;
 | 
			
		||||
 | 
			
		||||
- (void)loadThumbnail:(NSString *)path ofSize:(NSString *)size intoPath:(NSString *)destinationPath;
 | 
			
		||||
 | 
			
		||||
/* Uploads a file that will be named filename to the given root/path on the server. It will upload
 | 
			
		||||
   the contents of the file at sourcePath */
 | 
			
		||||
- (void)uploadFile:(NSString*)filename toPath:(NSString*)path fromPath:(NSString *)sourcePath;
 | 
			
		||||
 | 
			
		||||
/* Creates a folder at the given root/path */
 | 
			
		||||
- (void)createFolder:(NSString*)path;
 | 
			
		||||
 | 
			
		||||
- (void)deletePath:(NSString*)path;
 | 
			
		||||
 | 
			
		||||
- (void)copyFrom:(NSString*)from_path toPath:(NSString *)to_path;
 | 
			
		||||
 | 
			
		||||
- (void)moveFrom:(NSString*)from_path toPath:(NSString *)to_path;
 | 
			
		||||
 | 
			
		||||
- (void)loadAccountInfo;
 | 
			
		||||
 | 
			
		||||
- (void)createAccount:(NSString *)email password:(NSString *)password firstName:(NSString *)firstName 
 | 
			
		||||
        lastName:(NSString *)lastName;
 | 
			
		||||
 | 
			
		||||
- (void)setDelegate:(id)theDelegate;
 | 
			
		||||
- (id<DBRestClientDelegate>)delegate;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* The delegate provides allows the user to get the result of the calls made on the DBRestClient.
 | 
			
		||||
   Right now, the error parameter of failed calls may be nil and [error localizedDescription] does
 | 
			
		||||
   not contain an error message appropriate to show to the user. */
 | 
			
		||||
@protocol DBRestClientDelegate <NSObject>
 | 
			
		||||
 | 
			
		||||
@optional
 | 
			
		||||
 | 
			
		||||
- (void)restClientDidLogin:(DBRestClient*)client;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loginFailedWithError:(NSError*)error;
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client metadataUnchangedAtPath:(NSString*)path;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadMetadataFailedWithError:(NSError*)error; 
 | 
			
		||||
// [error userInfo] contains the root and path of the call that failed
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadedAccountInfo:(DBAccountInfo*)info;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadAccountInfoFailedWithError:(NSError*)error; 
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)destPath;
 | 
			
		||||
// Implement the following callback instead of the previous if you care about the value of the
 | 
			
		||||
// Content-Type HTTP header. Only one will be called per successful response.
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)destPath contentType:(NSString*)contentType;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadProgress:(float)progress forFile:(NSString*)destPath;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadFileFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the destinationPath
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadedThumbnail:(NSString*)destPath;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client loadThumbnailFailedWithError:(NSError*)error;
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client uploadedFile:(NSString*)destPath from:(NSString*)srcPath;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client uploadProgress:(float)progress 
 | 
			
		||||
forFile:(NSString*)destPath from:(NSString*)srcPath;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client uploadFileFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the sourcePath
 | 
			
		||||
 | 
			
		||||
// Deprecated upload callbacks
 | 
			
		||||
- (void)restClient:(DBRestClient*)client uploadedFile:(NSString*)srcPath;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client uploadProgress:(float)progress forFile:(NSString*)srcPath;
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client createdFolder:(DBMetadata*)folder;
 | 
			
		||||
// Folder is the metadata for the newly created folder
 | 
			
		||||
- (void)restClient:(DBRestClient*)client createFolderFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the root and path
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client deletedPath:(NSString *)path;
 | 
			
		||||
// Folder is the metadata for the newly created folder
 | 
			
		||||
- (void)restClient:(DBRestClient*)client deletePathFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the root and path
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)client copiedPath:(NSString *)from_path toPath:(NSString *)to_path;
 | 
			
		||||
// Folder is the metadata for the newly created folder
 | 
			
		||||
- (void)restClient:(DBRestClient*)client copyPathFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the root and path
 | 
			
		||||
//
 | 
			
		||||
- (void)restClient:(DBRestClient*)client movedPath:(NSString *)from_path toPath:(NSString *)to_path;
 | 
			
		||||
// Folder is the metadata for the newly created folder
 | 
			
		||||
- (void)restClient:(DBRestClient*)client movePathFailedWithError:(NSError*)error;
 | 
			
		||||
// [error userInfo] contains the root and path
 | 
			
		||||
 | 
			
		||||
- (void)restClientCreatedAccount:(DBRestClient*)client;
 | 
			
		||||
- (void)restClient:(DBRestClient*)client createAccountFailedWithError:(NSError *)error;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,846 +0,0 @@
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 | 
			
		||||
//
 | 
			
		||||
//  DBRestClient.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/9/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBRestClient.h"
 | 
			
		||||
#import "DBAccountInfo.h"
 | 
			
		||||
#import "DBError.h"
 | 
			
		||||
#import "DBMetadata.h"
 | 
			
		||||
#import "DBRequest.h"
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "MPOAuthSignatureParameter.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NSString* kDBProtocolHTTP = @"http";
 | 
			
		||||
NSString* kDBProtocolHTTPS = @"https";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface NSString (Addons)
 | 
			
		||||
- (NSString *)replace:(NSString *)targetString with:(NSString *)replaceString;
 | 
			
		||||
@end
 | 
			
		||||
@implementation NSString (Addons)
 | 
			
		||||
- (NSString *)replace:(NSString *)targetString with:(NSString *)replaceString {
 | 
			
		||||
	NSAutoreleasePool *pool = [NSAutoreleasePool new];
 | 
			
		||||
	NSMutableString *temp = [NSMutableString new];
 | 
			
		||||
	NSRange replaceRange = NSMakeRange(0, [self length]);
 | 
			
		||||
	NSRange rangeInOriginalString = replaceRange;
 | 
			
		||||
	int replaced = 0;
 | 
			
		||||
	
 | 
			
		||||
	while (1) {
 | 
			
		||||
		NSRange rangeToCopy;
 | 
			
		||||
		NSRange foundRange = [self rangeOfString:targetString options:0 range:rangeInOriginalString];
 | 
			
		||||
		if (foundRange.length == 0) break;
 | 
			
		||||
		rangeToCopy = NSMakeRange(rangeInOriginalString.location, foundRange.location - rangeInOriginalString.location);	
 | 
			
		||||
		[temp appendString:[self substringWithRange:rangeToCopy]];
 | 
			
		||||
		[temp appendString:replaceString];
 | 
			
		||||
		rangeInOriginalString.length -= NSMaxRange(foundRange) -
 | 
			
		||||
		rangeInOriginalString.location;
 | 
			
		||||
		rangeInOriginalString.location = NSMaxRange(foundRange);
 | 
			
		||||
		replaced++;
 | 
			
		||||
		if (replaced % 100 == 0) {
 | 
			
		||||
			[pool drain];
 | 
			
		||||
			pool = [NSAutoreleasePool new];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (rangeInOriginalString.length > 0) [temp appendString:[self substringWithRange:rangeInOriginalString]];
 | 
			
		||||
	[pool drain];
 | 
			
		||||
	
 | 
			
		||||
	return [temp autorelease];
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface DBRestClient ()
 | 
			
		||||
 | 
			
		||||
// This method escapes all URI escape characters except /
 | 
			
		||||
+ (NSString*)escapePath:(NSString*)path;
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)requestWithProtocol:(NSString*)protocol host:(NSString*)host path:(NSString*)path 
 | 
			
		||||
    parameters:(NSDictionary*)params;
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)requestWithProtocol:(NSString*)protocol host:(NSString*)host path:(NSString*)path 
 | 
			
		||||
    parameters:(NSDictionary*)params method:(NSString*)method;
 | 
			
		||||
 | 
			
		||||
- (void)checkForAuthenticationFailure:(DBRequest*)request;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation DBRestClient
 | 
			
		||||
 | 
			
		||||
- (id)initWithSession:(DBSession*)aSession {
 | 
			
		||||
    return [self initWithSession:aSession root:@"dropbox"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithSession:(DBSession*)aSession root:(NSString*)aRoot {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        session = [aSession retain];
 | 
			
		||||
        root = [aRoot retain];
 | 
			
		||||
        requests = [[NSMutableSet alloc] init];
 | 
			
		||||
        loadRequests = [[NSMutableDictionary alloc] init];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
	NSArray *requestsArray = [requests allObjects];
 | 
			
		||||
    for (int i=0; i<[requestsArray count]; i++) {
 | 
			
		||||
        [[requestsArray objectAtIndex:i] cancel];
 | 
			
		||||
    }
 | 
			
		||||
    [requests release];
 | 
			
		||||
    for (int i=0; i<[[loadRequests allValues] count]; i++) {
 | 
			
		||||
        [[[loadRequests allValues] objectAtIndex:i] cancel];
 | 
			
		||||
    }
 | 
			
		||||
    [loadRequests release];
 | 
			
		||||
    [session release];
 | 
			
		||||
    [root release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setDelegate:(id)theDelegate {
 | 
			
		||||
	delegate = theDelegate;
 | 
			
		||||
}
 | 
			
		||||
- (id<DBRestClientDelegate>)delegate {
 | 
			
		||||
	return delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)loginWithEmail:(NSString*)email password:(NSString*)password {
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            email, @"email",
 | 
			
		||||
            password, @"password", nil];
 | 
			
		||||
 | 
			
		||||
    NSURLRequest* urlRequest = [self requestWithProtocol:kDBProtocolHTTPS host:kDBDropboxAPIHost 
 | 
			
		||||
            path:@"/token" parameters:params];
 | 
			
		||||
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidLogin:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidLogin:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loginFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self loginFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary* result = (NSDictionary*)request.resultJSON;
 | 
			
		||||
        NSString* token = [result objectForKey:@"token"];
 | 
			
		||||
        NSString* secret = [result objectForKey:@"secret"];
 | 
			
		||||
        [session updateAccessToken:token accessTokenSecret:secret];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClientDidLogin:)]) {
 | 
			
		||||
            [delegate restClientDidLogin:self];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)loadMetadata:(NSString*)path withHash:(NSString*)hash
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = nil;
 | 
			
		||||
    if (hash) {
 | 
			
		||||
        params = [NSDictionary dictionaryWithObject:hash forKey:@"hash"];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSString* fullPath = [NSString stringWithFormat:@"/metadata/%@%@", root, path];
 | 
			
		||||
    NSURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:fullPath parameters:params];
 | 
			
		||||
    
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidLoadMetadata:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
    
 | 
			
		||||
    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:root, @"root", path, @"path", nil];
 | 
			
		||||
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)loadMetadata:(NSString*)path
 | 
			
		||||
{
 | 
			
		||||
    [self loadMetadata:path withHash:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidLoadMetadata:(DBRequest*)request
 | 
			
		||||
{
 | 
			
		||||
    if (request.statusCode == 304) {
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:metadataUnchangedAtPath:)]) {
 | 
			
		||||
            NSString* path = [request.userInfo objectForKey:@"path"];
 | 
			
		||||
            [delegate restClient:self metadataUnchangedAtPath:path];
 | 
			
		||||
        }
 | 
			
		||||
    } else if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadMetadataFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self loadMetadataFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
		[NSThread detachNewThreadSelector:@selector(parseMetadataWithRequest:) toTarget:self withObject:request];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)parseMetadataWithRequest:(DBRequest*)request {
 | 
			
		||||
    NSAutoreleasePool* pool = [NSAutoreleasePool new];
 | 
			
		||||
    
 | 
			
		||||
    NSDictionary* result = (NSDictionary*)[request resultJSON];
 | 
			
		||||
    DBMetadata* metadata = [[[DBMetadata alloc] initWithDictionary:result] autorelease];
 | 
			
		||||
    [self performSelectorOnMainThread:@selector(didParseMetadata:) withObject:metadata waitUntilDone:NO];
 | 
			
		||||
    
 | 
			
		||||
    [pool drain];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)didParseMetadata:(DBMetadata*)metadata {
 | 
			
		||||
    if ([delegate respondsToSelector:@selector(restClient:loadedMetadata:)]) {
 | 
			
		||||
        [delegate restClient:self loadedMetadata:metadata];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)loadFile:(NSString *)path intoPath:(NSString *)destinationPath
 | 
			
		||||
{
 | 
			
		||||
    NSString* fullPath = [NSString stringWithFormat:@"/files/%@%@", root, path];
 | 
			
		||||
    
 | 
			
		||||
    NSURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTPS host:kDBDropboxAPIContentHost path:fullPath parameters:nil];
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidLoadFile:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
    request.resultFilename = destinationPath;
 | 
			
		||||
    request.downloadProgressSelector = @selector(requestLoadProgress:);
 | 
			
		||||
    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root", 
 | 
			
		||||
            path, @"path", 
 | 
			
		||||
            destinationPath, @"destinationPath", nil];
 | 
			
		||||
    [loadRequests setObject:request forKey:path];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)cancelFileLoad:(NSString*)path {
 | 
			
		||||
    DBRequest* outstandingRequest = [loadRequests objectForKey:path];
 | 
			
		||||
    if (outstandingRequest) {
 | 
			
		||||
        [outstandingRequest cancel];
 | 
			
		||||
        [loadRequests removeObjectForKey:path];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestLoadProgress:(DBRequest*)request {
 | 
			
		||||
    if ([delegate respondsToSelector:@selector(restClient:loadProgress:forFile:)]) {
 | 
			
		||||
        [delegate restClient:self loadProgress:request.downloadProgress forFile:request.resultFilename];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient*)restClient loadedFile:(NSString*)destPath
 | 
			
		||||
contentType:(NSString*)contentType eTag:(NSString*)eTag {
 | 
			
		||||
	// Empty selector to get the signature from
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)requestDidLoadFile:(DBRequest*)request {
 | 
			
		||||
    NSString* path = [request.userInfo objectForKey:@"path"];
 | 
			
		||||
    
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadFileFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self loadFileFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSString* filename = request.resultFilename;
 | 
			
		||||
        NSDictionary* headers = [request.response allHeaderFields];
 | 
			
		||||
        NSString* contentType = [headers objectForKey:@"Content-Type"];
 | 
			
		||||
        NSString* eTag = [headers objectForKey:@"Etag"];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadedFile:)]) {
 | 
			
		||||
            [delegate restClient:self loadedFile:filename];
 | 
			
		||||
        } else if ([delegate respondsToSelector:@selector(restClient:loadedFile:contentType:)]) {
 | 
			
		||||
            [delegate restClient:self loadedFile:filename contentType:contentType];
 | 
			
		||||
        } else if ([delegate respondsToSelector:@selector(restClient:loadedFile:contentType:eTag:)]) {
 | 
			
		||||
			// This code is for the official Dropbox client to get eTag information from the server
 | 
			
		||||
			NSMethodSignature* signature = 
 | 
			
		||||
				[self methodSignatureForSelector:@selector(restClient:loadedFile:contentType:eTag:)];
 | 
			
		||||
			NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
 | 
			
		||||
			[invocation setTarget:delegate];
 | 
			
		||||
			[invocation setSelector:@selector(restClient:loadedFile:contentType:eTag:)];
 | 
			
		||||
			[invocation setArgument:&self atIndex:2];
 | 
			
		||||
			[invocation setArgument:&filename atIndex:3];
 | 
			
		||||
			[invocation setArgument:&contentType atIndex:4];
 | 
			
		||||
			[invocation setArgument:&eTag atIndex:5];
 | 
			
		||||
			[invocation invoke];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [loadRequests removeObjectForKey:path];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)loadThumbnail:(NSString *)path ofSize:(NSString *)size intoPath:(NSString *)destinationPath 
 | 
			
		||||
{
 | 
			
		||||
    NSString* fullPath = [NSString stringWithFormat:@"/thumbnails/%@%@", root, path];
 | 
			
		||||
    NSDictionary *params = nil;
 | 
			
		||||
 | 
			
		||||
    if(size) {
 | 
			
		||||
        params = [NSDictionary dictionaryWithObjectsAndKeys: size, @"size", nil];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIContentHost path:fullPath parameters:params];
 | 
			
		||||
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidLoadThumbnail:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
 | 
			
		||||
    request.resultFilename = destinationPath;
 | 
			
		||||
    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root", 
 | 
			
		||||
            path, @"path", 
 | 
			
		||||
            destinationPath, @"destinationPath", nil];
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidLoadThumbnail:(DBRequest*)request
 | 
			
		||||
{
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadThumbnailFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self loadThumbnailFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadedThumbnail:)]) {
 | 
			
		||||
            [delegate restClient:self loadedThumbnail:request.resultFilename];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NSString *createFakeSignature(DBSession *session, NSArray *params, NSString *filename, NSURL *baseUrl)
 | 
			
		||||
{
 | 
			
		||||
    NSArray* extraParams = [MPURLRequestParameter parametersFromDictionary:
 | 
			
		||||
            [NSDictionary dictionaryWithObject:filename forKey:@"file"]];
 | 
			
		||||
    
 | 
			
		||||
    NSMutableArray* paramList = [NSMutableArray arrayWithArray:params];
 | 
			
		||||
    [paramList addObjectsFromArray:extraParams];
 | 
			
		||||
    [paramList sortUsingSelector:@selector(compare:)];
 | 
			
		||||
    NSString* paramString = [MPURLRequestParameter parameterStringForParameters:paramList];
 | 
			
		||||
    
 | 
			
		||||
    MPOAuthURLRequest* oauthRequest = 
 | 
			
		||||
        [[[MPOAuthURLRequest alloc] initWithURL:baseUrl andParameters:paramList] autorelease];
 | 
			
		||||
    oauthRequest.HTTPMethod = @"POST";
 | 
			
		||||
    MPOAuthSignatureParameter *signatureParameter = 
 | 
			
		||||
        [[[MPOAuthSignatureParameter alloc] 
 | 
			
		||||
                initWithText:paramString andSecret:session.credentialStore.signingKey 
 | 
			
		||||
                forRequest:oauthRequest usingMethod:session.credentialStore.signatureMethod]
 | 
			
		||||
          autorelease];
 | 
			
		||||
 | 
			
		||||
    return [signatureParameter URLEncodedParameterString];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NSMutableURLRequest *createRealRequest(DBSession *session, NSArray *params, NSString *urlString, NSString *signatureText)
 | 
			
		||||
{
 | 
			
		||||
    NSMutableArray *paramList = [NSMutableArray arrayWithArray:params];
 | 
			
		||||
    // Then rebuild request using that signature
 | 
			
		||||
    [paramList sortUsingSelector:@selector(compare:)];
 | 
			
		||||
    NSMutableString* realParamString = [[[NSMutableString alloc] initWithString:
 | 
			
		||||
            [MPURLRequestParameter parameterStringForParameters:paramList]]
 | 
			
		||||
            autorelease];
 | 
			
		||||
    [realParamString appendFormat:@"&%@", signatureText];
 | 
			
		||||
    
 | 
			
		||||
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", urlString, realParamString]];
 | 
			
		||||
    NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
 | 
			
		||||
    urlRequest.HTTPMethod = @"POST";
 | 
			
		||||
 | 
			
		||||
    return urlRequest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns DBErrorNone if no errors were encountered
 | 
			
		||||
DBErrorCode addFileUploadToRequest(NSMutableURLRequest *urlRequest, NSString *filename, NSString *sourcePath)
 | 
			
		||||
{
 | 
			
		||||
    // Create input stream
 | 
			
		||||
    CFUUIDRef uuid = CFUUIDCreate(NULL);
 | 
			
		||||
    NSString* stringBoundary = [(NSString*)CFUUIDCreateString(NULL, uuid) autorelease];
 | 
			
		||||
    CFRelease(uuid);
 | 
			
		||||
 | 
			
		||||
    NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
 | 
			
		||||
    [urlRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
 | 
			
		||||
    
 | 
			
		||||
    NSString* tempFilename = 
 | 
			
		||||
        [NSString stringWithFormat: @"%.0f.txt", [NSDate timeIntervalSinceReferenceDate] * 1000.0];
 | 
			
		||||
    NSString *tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:tempFilename];
 | 
			
		||||
 | 
			
		||||
    //setting up the body
 | 
			
		||||
    NSMutableData* bodyData = [NSMutableData data];
 | 
			
		||||
    [bodyData appendData:
 | 
			
		||||
            [[NSString stringWithFormat:@"--%@\r\n", stringBoundary] 
 | 
			
		||||
             dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
 | 
			
		||||
    // Add data to upload
 | 
			
		||||
    [bodyData appendData:
 | 
			
		||||
            [[NSString stringWithFormat:
 | 
			
		||||
                @"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", filename] 
 | 
			
		||||
             dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
    [bodyData appendData:
 | 
			
		||||
            [[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] 
 | 
			
		||||
             dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
             
 | 
			
		||||
    if (![[NSFileManager defaultManager] createFileAtPath:tempFilePath contents:bodyData attributes:nil]) {
 | 
			
		||||
        NSLog(@"DBRestClient#uploadFileToRoot:path:filename:fromPath: failed to create file");
 | 
			
		||||
        return DBErrorGenericError;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NSFileHandle* bodyFile = [NSFileHandle fileHandleForWritingAtPath:tempFilePath];
 | 
			
		||||
    [bodyFile seekToEndOfFile];
 | 
			
		||||
 | 
			
		||||
    if ([[NSFileManager defaultManager] fileExistsAtPath:sourcePath]) {
 | 
			
		||||
        NSFileHandle* readFile = [NSFileHandle fileHandleForReadingAtPath:sourcePath];
 | 
			
		||||
        NSData* readData;
 | 
			
		||||
        while ((readData = [readFile readDataOfLength:1024 * 512]) != nil && [readData length] > 0) {
 | 
			
		||||
            @try {
 | 
			
		||||
                [bodyFile writeData:readData];
 | 
			
		||||
            } @catch (NSException* e) {
 | 
			
		||||
                NSLog(@"DBRestClient#uploadFileToRoot:path:filename:fromPath: failed to write data");
 | 
			
		||||
                [readFile closeFile];
 | 
			
		||||
                [bodyFile closeFile];
 | 
			
		||||
                NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
				if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
					[manager removeFileAtPath:tempFilePath handler:nil];
 | 
			
		||||
				else
 | 
			
		||||
					[manager removeItemAtPath:tempFilePath error:nil];
 | 
			
		||||
                return DBErrorInsufficientDiskSpace;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        [readFile closeFile];
 | 
			
		||||
    } else {
 | 
			
		||||
        NSLog(@"DBRestClient#uploadFileToRoot:path:filename:fromPath: unable to open sourceFile");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @try {
 | 
			
		||||
        [bodyFile writeData:
 | 
			
		||||
                [[NSString stringWithFormat:@"\r\n--%@--\r\n", stringBoundary] 
 | 
			
		||||
                 dataUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
    } @catch (NSException* e) {
 | 
			
		||||
        NSLog(@"DBRestClient#uploadFileToRoot:path:filename:fromPath: failed to write end of data");
 | 
			
		||||
        [bodyFile closeFile];
 | 
			
		||||
        NSFileManager *manager = [NSFileManager defaultManager];
 | 
			
		||||
		if ([manager respondsToSelector:@selector(removeFileAtPath:handler:)])
 | 
			
		||||
			[manager removeFileAtPath:tempFilePath handler:nil];
 | 
			
		||||
		else
 | 
			
		||||
			[manager removeItemAtPath:tempFilePath error:nil];
 | 
			
		||||
        return DBErrorInsufficientDiskSpace;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSString* contentLength = [NSString stringWithFormat: @"%qu", [bodyFile offsetInFile]];
 | 
			
		||||
    [urlRequest addValue:contentLength forHTTPHeaderField: @"Content-Length"];    
 | 
			
		||||
    [bodyFile closeFile];
 | 
			
		||||
	
 | 
			
		||||
    urlRequest.HTTPBodyStream = [NSInputStream inputStreamWithFileAtPath:tempFilePath];
 | 
			
		||||
 | 
			
		||||
    return DBErrorNone;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)uploadFile:(NSString*)filename toPath:(NSString*)path fromPath:(NSString *)sourcePath
 | 
			
		||||
{
 | 
			
		||||
    if (![[NSFileManager defaultManager] fileExistsAtPath:sourcePath]) {
 | 
			
		||||
        NSDictionary* userInfo = [NSDictionary dictionaryWithObject:sourcePath forKey:@"sourcePath"];
 | 
			
		||||
        NSError* error = 
 | 
			
		||||
            [NSError errorWithDomain:DBErrorDomain code:DBErrorFileNotFound userInfo:userInfo];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:uploadFileFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self uploadFileFailedWithError:error];
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // path is the directory the file will be uploaded to, make sure it doesn't have a trailing /
 | 
			
		||||
    // (unless it's the root dir) and is properly escaped
 | 
			
		||||
    NSString* trimmedPath;
 | 
			
		||||
    if ([path length] > 1 && [path characterAtIndex:[path length]-1] == '/') {
 | 
			
		||||
        trimmedPath = [path substringToIndex:[path length]-1];
 | 
			
		||||
    } else {
 | 
			
		||||
        trimmedPath = path;
 | 
			
		||||
    }
 | 
			
		||||
    NSString* escapedPath = [DBRestClient escapePath:trimmedPath];
 | 
			
		||||
    
 | 
			
		||||
    NSString* urlString = [NSString stringWithFormat:@"%@://%@/%@/files/%@%@", 
 | 
			
		||||
            kDBProtocolHTTPS, kDBDropboxAPIContentHost, kDBDropboxAPIVersion, root, escapedPath];
 | 
			
		||||
    NSURL* baseUrl = [NSURL URLWithString:urlString];
 | 
			
		||||
    NSArray* params = [session.credentialStore oauthParameters];
 | 
			
		||||
 | 
			
		||||
    NSString *escapedFilename = [filename replace:@";" with:@"-"];
 | 
			
		||||
 | 
			
		||||
    NSString *signatureText = createFakeSignature(session, params, escapedFilename, baseUrl);
 | 
			
		||||
 | 
			
		||||
    NSMutableURLRequest *urlRequest = createRealRequest(session, params, urlString, signatureText);
 | 
			
		||||
   
 | 
			
		||||
    DBErrorCode errorCode = addFileUploadToRequest(urlRequest, escapedFilename, sourcePath);
 | 
			
		||||
    if(errorCode == DBErrorNone) {
 | 
			
		||||
        DBRequest* request = 
 | 
			
		||||
            [[[DBRequest alloc] 
 | 
			
		||||
              initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidUploadFile:)]
 | 
			
		||||
             autorelease];
 | 
			
		||||
        request.uploadProgressSelector = @selector(requestUploadProgress:);
 | 
			
		||||
        NSString* dropboxPath = [path stringByAppendingPathComponent:filename];
 | 
			
		||||
        request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                root, @"root", 
 | 
			
		||||
                path, @"path",
 | 
			
		||||
                dropboxPath, @"destinationPath",
 | 
			
		||||
                sourcePath, @"sourcePath", nil];
 | 
			
		||||
        [requests addObject:request];
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary* userInfo = [NSDictionary dictionaryWithObject:sourcePath forKey:@"sourcePath"];
 | 
			
		||||
        NSError* error = 
 | 
			
		||||
            [NSError errorWithDomain:DBErrorDomain code:errorCode userInfo:userInfo];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:uploadFileFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self uploadFileFailedWithError:error];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestUploadProgress:(DBRequest*)request {
 | 
			
		||||
    NSString* sourcePath = [(NSDictionary*)request.userInfo objectForKey:@"sourcePath"];
 | 
			
		||||
    NSString* destPath = [request.userInfo objectForKey:@"destinationPath"];
 | 
			
		||||
 | 
			
		||||
    if ([delegate respondsToSelector:@selector(restClient:uploadProgress:forFile:from:)]) {
 | 
			
		||||
        [delegate restClient:self uploadProgress:request.uploadProgress
 | 
			
		||||
                    forFile:destPath from:sourcePath];
 | 
			
		||||
    } else if ([delegate respondsToSelector:@selector(restClient:uploadProgress:forFile:)]) {
 | 
			
		||||
        [delegate restClient:self uploadProgress:request.uploadProgress forFile:sourcePath];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidUploadFile:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:uploadFileFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self uploadFileFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSString* sourcePath = [(NSDictionary*)request.userInfo objectForKey:@"sourcePath"];
 | 
			
		||||
        NSString* destPath = [request.userInfo objectForKey:@"destinationPath"];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:uploadedFile:from:)]) {
 | 
			
		||||
            [delegate restClient:self uploadedFile:destPath from:sourcePath];
 | 
			
		||||
        } else if ([delegate respondsToSelector:@selector(restClient:uploadedFile:)]) {
 | 
			
		||||
            [delegate restClient:self uploadedFile:sourcePath];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)moveFrom:(NSString*)from_path toPath:(NSString *)to_path
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root",
 | 
			
		||||
            from_path, @"from_path",
 | 
			
		||||
            to_path, @"to_path", nil];
 | 
			
		||||
            
 | 
			
		||||
    NSMutableURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:@"/fileops/move"
 | 
			
		||||
                parameters:params method:@"POST"];
 | 
			
		||||
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidMovePath:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
 | 
			
		||||
    request.userInfo = params;
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidMovePath:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:movePathFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self movePathFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary *params = (NSDictionary *)request.userInfo;
 | 
			
		||||
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:movedPath:toPath:)]) {
 | 
			
		||||
            [delegate restClient:self movedPath:[params valueForKey:@"from_path"] 
 | 
			
		||||
                        toPath:[params valueForKey:@"to_path"]];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)copyFrom:(NSString*)from_path toPath:(NSString *)to_path
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root",
 | 
			
		||||
            from_path, @"from_path",
 | 
			
		||||
            to_path, @"to_path", nil];
 | 
			
		||||
            
 | 
			
		||||
    NSMutableURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:@"/fileops/copy"
 | 
			
		||||
                parameters:params method:@"POST"];
 | 
			
		||||
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidCopyPath:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
 | 
			
		||||
    request.userInfo = params;
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidCopyPath:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:copyPathFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self copyPathFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary *params = (NSDictionary *)request.userInfo;
 | 
			
		||||
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:copiedPath:toPath:)]) {
 | 
			
		||||
            [delegate restClient:self copiedPath:[params valueForKey:@"from_path"] 
 | 
			
		||||
                        toPath:[params valueForKey:@"to_path"]];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)deletePath:(NSString*)path
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root",
 | 
			
		||||
            path, @"path", nil];
 | 
			
		||||
            
 | 
			
		||||
    NSMutableURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:@"/fileops/delete" 
 | 
			
		||||
                parameters:params method:@"POST"];
 | 
			
		||||
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidDeletePath:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
 | 
			
		||||
    request.userInfo = params;
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidDeletePath:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:deletePathFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self deletePathFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:deletedPath:)]) {
 | 
			
		||||
            NSString* path = [request.userInfo objectForKey:@"path"];
 | 
			
		||||
            [delegate restClient:self deletedPath:path];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)createFolder:(NSString*)path
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
            root, @"root",
 | 
			
		||||
            path, @"path", nil];
 | 
			
		||||
            
 | 
			
		||||
    NSString* fullPath = @"/fileops/create_folder";
 | 
			
		||||
    NSMutableURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:fullPath 
 | 
			
		||||
                parameters:params method:@"POST"];
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidCreateDirectory:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
    request.userInfo = params;
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidCreateDirectory:(DBRequest*)request {
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:createFolderFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self createFolderFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary* result = (NSDictionary*)[request resultJSON];
 | 
			
		||||
        DBMetadata* metadata = [[[DBMetadata alloc] initWithDictionary:result] autorelease];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:createdFolder:)]) {
 | 
			
		||||
            [delegate restClient:self createdFolder:metadata];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)loadAccountInfo
 | 
			
		||||
{
 | 
			
		||||
    NSURLRequest* urlRequest = 
 | 
			
		||||
        [self requestWithProtocol:kDBProtocolHTTP host:kDBDropboxAPIHost path:@"/account/info" parameters:nil];
 | 
			
		||||
    
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidLoadAccountInfo:)]
 | 
			
		||||
         autorelease];
 | 
			
		||||
    
 | 
			
		||||
    request.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:root, @"root", nil];
 | 
			
		||||
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)requestDidLoadAccountInfo:(DBRequest*)request
 | 
			
		||||
{
 | 
			
		||||
    if (request.error) {
 | 
			
		||||
        [self checkForAuthenticationFailure:request];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadAccountInfoFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self loadAccountInfoFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        NSDictionary* result = (NSDictionary*)[request resultJSON];
 | 
			
		||||
        DBAccountInfo* accountInfo = [[[DBAccountInfo alloc] initWithDictionary:result] autorelease];
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClient:loadedAccountInfo:)]) {
 | 
			
		||||
            [delegate restClient:self loadedAccountInfo:accountInfo];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)createAccount:(NSString *)email password:(NSString *)password firstName:(NSString *)firstName lastName:(NSString *)lastName
 | 
			
		||||
{
 | 
			
		||||
    NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                            email, @"email",
 | 
			
		||||
                            password, @"password",
 | 
			
		||||
                            firstName, @"first_name",
 | 
			
		||||
                            lastName, @"last_name", nil];
 | 
			
		||||
    
 | 
			
		||||
    NSString* fullPath = @"/account";
 | 
			
		||||
    NSMutableURLRequest* urlRequest = 
 | 
			
		||||
    [self requestWithProtocol:kDBProtocolHTTPS host:kDBDropboxAPIHost path:fullPath 
 | 
			
		||||
                   parameters:params method:@"POST"];
 | 
			
		||||
    
 | 
			
		||||
    DBRequest* request = 
 | 
			
		||||
        [[[DBRequest alloc] 
 | 
			
		||||
          initWithURLRequest:urlRequest andInformTarget:self selector:@selector(requestDidCreateAccount:)]
 | 
			
		||||
            autorelease];
 | 
			
		||||
 | 
			
		||||
    request.userInfo = params;
 | 
			
		||||
    
 | 
			
		||||
    [requests addObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)requestDidCreateAccount:(DBRequest *)request
 | 
			
		||||
{
 | 
			
		||||
    if(request.error) {
 | 
			
		||||
        if([delegate respondsToSelector:@selector(restClient:createAccountFailedWithError:)]) {
 | 
			
		||||
            [delegate restClient:self createAccountFailedWithError:request.error];
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if ([delegate respondsToSelector:@selector(restClientCreatedAccount:)]) {
 | 
			
		||||
            [delegate restClientCreatedAccount:self];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    [requests removeObject:request];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma mark private methods
 | 
			
		||||
 | 
			
		||||
+ (NSString*)escapePath:(NSString*)path {
 | 
			
		||||
    CFStringEncoding encoding = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
 | 
			
		||||
    NSString *escapedPath = 
 | 
			
		||||
        (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
 | 
			
		||||
                                                            (CFStringRef)path,
 | 
			
		||||
                                                            NULL,
 | 
			
		||||
                                                            (CFStringRef)@":?=,!$&'()*+;[]@#~",
 | 
			
		||||
                                                            encoding);
 | 
			
		||||
    
 | 
			
		||||
    return [escapedPath autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)requestWithProtocol:(NSString*)protocol host:(NSString*)host path:(NSString*)path 
 | 
			
		||||
    parameters:(NSDictionary*)params {
 | 
			
		||||
    
 | 
			
		||||
    return [self requestWithProtocol:protocol host:host path:path parameters:params method:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)requestWithProtocol:(NSString*)protocol host:(NSString*)host path:(NSString*)path 
 | 
			
		||||
    parameters:(NSDictionary*)params method:(NSString*)method {
 | 
			
		||||
    
 | 
			
		||||
    NSString* escapedPath = [DBRestClient escapePath:path];
 | 
			
		||||
    NSString* urlString = [NSString stringWithFormat:@"%@://%@/%@%@", 
 | 
			
		||||
                                        protocol, host, kDBDropboxAPIVersion, escapedPath];
 | 
			
		||||
    NSURL* url = [NSURL URLWithString:urlString];
 | 
			
		||||
    
 | 
			
		||||
    NSArray* paramList = [session.credentialStore oauthParameters];
 | 
			
		||||
    if ([params count] > 0) {
 | 
			
		||||
        NSArray* extraParams = [MPURLRequestParameter parametersFromDictionary:params];
 | 
			
		||||
        paramList = [paramList arrayByAddingObjectsFromArray:extraParams];
 | 
			
		||||
    }
 | 
			
		||||
    MPOAuthURLRequest* oauthRequest = 
 | 
			
		||||
        [[[MPOAuthURLRequest alloc] initWithURL:url andParameters:paramList] autorelease];
 | 
			
		||||
    if (method) {
 | 
			
		||||
        oauthRequest.HTTPMethod = method;
 | 
			
		||||
    }
 | 
			
		||||
    NSMutableURLRequest* urlRequest = [oauthRequest 
 | 
			
		||||
            urlRequestSignedWithSecret:session.credentialStore.signingKey 
 | 
			
		||||
            usingMethod:session.credentialStore.signatureMethod];
 | 
			
		||||
    return urlRequest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (void)checkForAuthenticationFailure:(DBRequest*)request {
 | 
			
		||||
    if (request.error && request.error.code == 401 && [request.error.domain isEqual:@"dropbox.com"]) {
 | 
			
		||||
        [session.delegate sessionDidReceiveAuthorizationFailure:session];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBSession.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/8/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
 | 
			
		||||
extern NSString* kDBDropboxAPIHost;
 | 
			
		||||
extern NSString* kDBDropboxAPIContentHost;
 | 
			
		||||
extern NSString* kDBDropboxAPIVersion;
 | 
			
		||||
 | 
			
		||||
@protocol DBSessionDelegate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*  Creating and setting the shared DBSession should be done before any other Dropbox objects are
 | 
			
		||||
    used, perferrably in the UIApplication delegate. */
 | 
			
		||||
@interface DBSession : NSObject {
 | 
			
		||||
    MPOAuthCredentialConcreteStore *credentialStore;
 | 
			
		||||
    id<DBSessionDelegate> delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (DBSession*)sharedSession;
 | 
			
		||||
+ (void)setSharedSession:(DBSession*)session;
 | 
			
		||||
 | 
			
		||||
- (id)initWithConsumerKey:(NSString*)key consumerSecret:(NSString*)secret;
 | 
			
		||||
- (BOOL)isLinked; // If not linked, you can only call loginWithEmail:password from the DBRestClient
 | 
			
		||||
 | 
			
		||||
- (void)updateAccessToken:(NSString*)token accessTokenSecret:(NSString*)secret;
 | 
			
		||||
- (void)unlink;
 | 
			
		||||
 | 
			
		||||
- (MPOAuthCredentialConcreteStore *)credentialStore;
 | 
			
		||||
- (void)setDelegate:(id)theDelegate;
 | 
			
		||||
- (id<DBSessionDelegate>)delegate;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@protocol DBSessionDelegate
 | 
			
		||||
 | 
			
		||||
- (void)sessionDidReceiveAuthorizationFailure:(DBSession*)session;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,123 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  DBSession.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 4/8/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "DBSession.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPOAuthSignatureParameter.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
NSString* kDBDropboxAPIHost = @"api.dropbox.com";
 | 
			
		||||
NSString* kDBDropboxAPIContentHost = @"api-content.dropbox.com";
 | 
			
		||||
NSString* kDBDropboxAPIVersion = @"0";
 | 
			
		||||
 | 
			
		||||
static DBSession* _sharedSession = nil;
 | 
			
		||||
//static DBSession* kDBDropboxSavedCredentialsKey = @"kDBDropboxSavedCredentialsKey";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface DBSession ()
 | 
			
		||||
 | 
			
		||||
- (NSDictionary*)savedCredentials;
 | 
			
		||||
- (void)saveCredentials:(NSDictionary*)credentials;
 | 
			
		||||
- (void)clearSavedCredentials;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation DBSession
 | 
			
		||||
 | 
			
		||||
+ (DBSession*)sharedSession {
 | 
			
		||||
    return _sharedSession;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (void)setSharedSession:(DBSession*)session {
 | 
			
		||||
    if (session == _sharedSession) return;
 | 
			
		||||
    [_sharedSession release];
 | 
			
		||||
    _sharedSession = [session retain];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithConsumerKey:(NSString*)key consumerSecret:(NSString*)secret {
 | 
			
		||||
    if ((self = [super init])) {
 | 
			
		||||
        
 | 
			
		||||
        NSMutableDictionary* credentials = 
 | 
			
		||||
            [NSMutableDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                key, kMPOAuthCredentialConsumerKey,
 | 
			
		||||
                secret, kMPOAuthCredentialConsumerSecret, 
 | 
			
		||||
                kMPOAuthSignatureMethodHMACSHA1, kMPOAuthSignatureMethod, nil];
 | 
			
		||||
        
 | 
			
		||||
        NSDictionary* savedCredentials = [self savedCredentials];
 | 
			
		||||
        if (savedCredentials != nil) {
 | 
			
		||||
            if ([key isEqualToString:[savedCredentials objectForKey:kMPOAuthCredentialConsumerKey]]) {
 | 
			
		||||
                
 | 
			
		||||
                [credentials setObject:[savedCredentials objectForKey:kMPOAuthCredentialAccessToken] 
 | 
			
		||||
                    forKey:kMPOAuthCredentialAccessToken];
 | 
			
		||||
                [credentials setObject:[savedCredentials objectForKey:kMPOAuthCredentialAccessTokenSecret] 
 | 
			
		||||
                    forKey:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
            } else {
 | 
			
		||||
                [self clearSavedCredentials];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        credentialStore = [[MPOAuthCredentialConcreteStore alloc] initWithCredentials:credentials];
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [credentialStore release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPOAuthCredentialConcreteStore *)credentialStore {
 | 
			
		||||
	return credentialStore;
 | 
			
		||||
}
 | 
			
		||||
- (void)setDelegate:(id)theDelegate {
 | 
			
		||||
	delegate = theDelegate;
 | 
			
		||||
}
 | 
			
		||||
- (id<DBSessionDelegate>)delegate {
 | 
			
		||||
	return delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)updateAccessToken:(NSString*)token accessTokenSecret:(NSString*)secret {
 | 
			
		||||
    credentialStore.accessToken = token;
 | 
			
		||||
    credentialStore.accessTokenSecret = secret;
 | 
			
		||||
    NSDictionary* credentials = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
        credentialStore.consumerKey, kMPOAuthCredentialConsumerKey,
 | 
			
		||||
        credentialStore.accessToken, kMPOAuthCredentialAccessToken,
 | 
			
		||||
        credentialStore.accessTokenSecret, kMPOAuthCredentialAccessTokenSecret,
 | 
			
		||||
        nil];
 | 
			
		||||
    [self saveCredentials:credentials];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL) isLinked {
 | 
			
		||||
    return credentialStore.accessToken != nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)unlink {
 | 
			
		||||
    credentialStore.accessToken = nil;
 | 
			
		||||
    credentialStore.accessTokenSecret = nil;
 | 
			
		||||
    [self clearSavedCredentials];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark private methods
 | 
			
		||||
 | 
			
		||||
- (NSDictionary*)savedCredentials {
 | 
			
		||||
    return nil;//[[NSUserDefaults standardUserDefaults] objectForKey:kDBDropboxSavedCredentialsKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)saveCredentials:(NSDictionary*)credentials {
 | 
			
		||||
    if (credentials == nil) return;
 | 
			
		||||
    
 | 
			
		||||
    //[[NSUserDefaults standardUserDefaults] setObject:credentials forKey:kDBDropboxSavedCredentialsKey];
 | 
			
		||||
    //[[NSUserDefaults standardUserDefaults] synchronize];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearSavedCredentials {
 | 
			
		||||
    //[[NSUserDefaults standardUserDefaults] removeObjectForKey:kDBDropboxSavedCredentialsKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  DropboxSDK.h
 | 
			
		||||
 *  DropboxSDK
 | 
			
		||||
 *
 | 
			
		||||
 *  Created by Brian Smith on 7/13/10.
 | 
			
		||||
 *  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Import this file to get the most important header files imported */
 | 
			
		||||
#import "DBSession.h"
 | 
			
		||||
#import "DBRestClient.h"
 | 
			
		||||
#import "DBLoginController.h"
 | 
			
		||||
#import "DBAccountInfo.h"
 | 
			
		||||
#import "DBMetadata.h"
 | 
			
		||||
#import "DBQuota.h"
 | 
			
		||||
#import "DBError.h"
 | 
			
		||||
@ -1,50 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @mainpage A strict JSON parser and generator for Objective-C
 | 
			
		||||
 | 
			
		||||
 JSON (JavaScript Object Notation) is a lightweight data-interchange
 | 
			
		||||
 format. This framework provides two apis for parsing and generating
 | 
			
		||||
 JSON. One standard object-based and a higher level api consisting of
 | 
			
		||||
 categories added to existing Objective-C classes.
 | 
			
		||||
 | 
			
		||||
 Learn more on the http://code.google.com/p/json-framework project site.
 | 
			
		||||
 
 | 
			
		||||
 This framework does its best to be as strict as possible, both in what it
 | 
			
		||||
 accepts and what it generates. For example, it does not support trailing commas
 | 
			
		||||
 in arrays or objects. Nor does it support embedded comments, or
 | 
			
		||||
 anything else not in the JSON specification. This is considered a feature. 
 | 
			
		||||
 
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#import "SBJSON.h"
 | 
			
		||||
#import "NSObject+SBJSON.h"
 | 
			
		||||
#import "NSString+SBJSON.h"
 | 
			
		||||
 | 
			
		||||
@ -1,68 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Adds JSON generation to Foundation classes
 | 
			
		||||
 
 | 
			
		||||
 This is a category on NSObject that adds methods for returning JSON representations
 | 
			
		||||
 of standard objects to the objects themselves. This means you can call the
 | 
			
		||||
 -JSONRepresentation method on an NSArray object and it'll do what you want.
 | 
			
		||||
 */
 | 
			
		||||
@interface NSObject (NSObject_SBJSON)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Returns a string containing the receiver encoded as a JSON fragment.
 | 
			
		||||
 
 | 
			
		||||
 This method is added as a category on NSObject but is only actually
 | 
			
		||||
 supported for the following objects:
 | 
			
		||||
 @li NSDictionary
 | 
			
		||||
 @li NSArray
 | 
			
		||||
 @li NSString
 | 
			
		||||
 @li NSNumber (also used for booleans)
 | 
			
		||||
 @li NSNull 
 | 
			
		||||
 
 | 
			
		||||
 @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
 | 
			
		||||
 */
 | 
			
		||||
- (NSString *)JSONFragment;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Returns a string containing the receiver encoded in JSON.
 | 
			
		||||
 | 
			
		||||
 This method is added as a category on NSObject but is only actually
 | 
			
		||||
 supported for the following objects:
 | 
			
		||||
 @li NSDictionary
 | 
			
		||||
 @li NSArray
 | 
			
		||||
 */
 | 
			
		||||
- (NSString *)JSONRepresentation;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@ -1,53 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "NSObject+SBJSON.h"
 | 
			
		||||
#import "SBJsonWriter.h"
 | 
			
		||||
 | 
			
		||||
@implementation NSObject (NSObject_SBJSON)
 | 
			
		||||
 | 
			
		||||
- (NSString *)JSONFragment {
 | 
			
		||||
    SBJsonWriter *jsonWriter = [SBJsonWriter new];
 | 
			
		||||
    NSString *json = [jsonWriter stringWithFragment:self];    
 | 
			
		||||
    if (!json)
 | 
			
		||||
        NSLog(@"-JSONFragment failed. Error trace is: %@", [jsonWriter errorTrace]);
 | 
			
		||||
    [jsonWriter release];
 | 
			
		||||
    return json;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)JSONRepresentation {
 | 
			
		||||
    SBJsonWriter *jsonWriter = [SBJsonWriter new];    
 | 
			
		||||
    NSString *json = [jsonWriter stringWithObject:self];
 | 
			
		||||
    if (!json)
 | 
			
		||||
        NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]);
 | 
			
		||||
    [jsonWriter release];
 | 
			
		||||
    return json;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,58 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Adds JSON parsing methods to NSString
 | 
			
		||||
 
 | 
			
		||||
This is a category on NSString that adds methods for parsing the target string.
 | 
			
		||||
*/
 | 
			
		||||
@interface NSString (NSString_SBJSON)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Returns the object represented in the receiver, or nil on error. 
 | 
			
		||||
 
 | 
			
		||||
 Returns a a scalar object represented by the string's JSON fragment representation.
 | 
			
		||||
 
 | 
			
		||||
 @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
 | 
			
		||||
 */
 | 
			
		||||
- (id)JSONFragmentValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation.
 | 
			
		||||
 
 | 
			
		||||
 Returns the dictionary or array represented in the receiver, or nil on error.
 | 
			
		||||
 | 
			
		||||
 Returns the NSDictionary or NSArray represented by the current string's JSON representation.
 | 
			
		||||
 */
 | 
			
		||||
- (id)JSONValue;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,55 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2007-2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "NSString+SBJSON.h"
 | 
			
		||||
#import "SBJsonParser.h"
 | 
			
		||||
 | 
			
		||||
@implementation NSString (NSString_SBJSON)
 | 
			
		||||
 | 
			
		||||
- (id)JSONFragmentValue
 | 
			
		||||
{
 | 
			
		||||
    SBJsonParser *jsonParser = [SBJsonParser new];    
 | 
			
		||||
    id repr = [jsonParser fragmentWithString:self];    
 | 
			
		||||
    if (!repr)
 | 
			
		||||
        NSLog(@"-JSONFragmentValue failed. Error trace is: %@", [jsonParser errorTrace]);
 | 
			
		||||
    [jsonParser release];
 | 
			
		||||
    return repr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)JSONValue
 | 
			
		||||
{
 | 
			
		||||
    SBJsonParser *jsonParser = [SBJsonParser new];
 | 
			
		||||
    id repr = [jsonParser objectWithString:self];
 | 
			
		||||
    if (!repr)
 | 
			
		||||
        NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]);
 | 
			
		||||
    [jsonParser release];
 | 
			
		||||
    return repr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,75 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2007-2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "SBJsonParser.h"
 | 
			
		||||
#import "SBJsonWriter.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Facade for SBJsonWriter/SBJsonParser.
 | 
			
		||||
 | 
			
		||||
 Requests are forwarded to instances of SBJsonWriter and SBJsonParser.
 | 
			
		||||
 */
 | 
			
		||||
@interface SBJSON : SBJsonBase <SBJsonParser, SBJsonWriter> {
 | 
			
		||||
 | 
			
		||||
@private    
 | 
			
		||||
    SBJsonParser *jsonParser;
 | 
			
		||||
    SBJsonWriter *jsonWriter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Return the fragment represented by the given string
 | 
			
		||||
- (id)fragmentWithString:(NSString*)jsonrep
 | 
			
		||||
                   error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
/// Return the object represented by the given string
 | 
			
		||||
- (id)objectWithString:(NSString*)jsonrep
 | 
			
		||||
                 error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
/// Parse the string and return the represented object (or scalar)
 | 
			
		||||
- (id)objectWithString:(id)value
 | 
			
		||||
           allowScalar:(BOOL)x
 | 
			
		||||
    			 error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Return JSON representation of an array  or dictionary
 | 
			
		||||
- (NSString*)stringWithObject:(id)value
 | 
			
		||||
                        error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
/// Return JSON representation of any legal JSON value
 | 
			
		||||
- (NSString*)stringWithFragment:(id)value
 | 
			
		||||
                          error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
/// Return JSON representation (or fragment) for the given object
 | 
			
		||||
- (NSString*)stringWithObject:(id)value
 | 
			
		||||
                  allowScalar:(BOOL)x
 | 
			
		||||
    					error:(NSError**)error;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,213 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2007-2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "SBJSON.h"
 | 
			
		||||
 | 
			
		||||
@implementation SBJSON
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
    self = [super init];
 | 
			
		||||
    if (self) {
 | 
			
		||||
        jsonWriter = [SBJsonWriter new];
 | 
			
		||||
        jsonParser = [SBJsonParser new];
 | 
			
		||||
        [self setMaxDepth:512];
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [jsonWriter release];
 | 
			
		||||
    [jsonParser release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Writer 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringWithObject:(id)obj {
 | 
			
		||||
    NSString *repr = [jsonWriter stringWithObject:obj];
 | 
			
		||||
    if (repr)
 | 
			
		||||
        return repr;
 | 
			
		||||
    
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    errorTrace = [[jsonWriter errorTrace] mutableCopy];
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns a string containing JSON representation of the passed in value, or nil on error.
 | 
			
		||||
 If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
 | 
			
		||||
 
 | 
			
		||||
 @param value any instance that can be represented as a JSON fragment
 | 
			
		||||
 @param allowScalar wether to return json fragments for scalar objects
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 
 | 
			
		||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
 | 
			
		||||
 */
 | 
			
		||||
- (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
 | 
			
		||||
    
 | 
			
		||||
    NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value];
 | 
			
		||||
    if (json)
 | 
			
		||||
        return json;
 | 
			
		||||
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    errorTrace = [[jsonWriter errorTrace] mutableCopy];
 | 
			
		||||
    
 | 
			
		||||
    if (error)
 | 
			
		||||
        *error = [errorTrace lastObject];
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns a string containing JSON representation of the passed in value, or nil on error.
 | 
			
		||||
 If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
 | 
			
		||||
 
 | 
			
		||||
 @param value any instance that can be represented as a JSON fragment
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 
 | 
			
		||||
 @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
 | 
			
		||||
 */
 | 
			
		||||
- (NSString*)stringWithFragment:(id)value error:(NSError**)error {
 | 
			
		||||
    return [self stringWithObject:value
 | 
			
		||||
                      allowScalar:YES
 | 
			
		||||
                            error:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns a string containing JSON representation of the passed in value, or nil on error.
 | 
			
		||||
 If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
 | 
			
		||||
 
 | 
			
		||||
 @param value a NSDictionary or NSArray instance
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 */
 | 
			
		||||
- (NSString*)stringWithObject:(id)value error:(NSError**)error {
 | 
			
		||||
    return [self stringWithObject:value
 | 
			
		||||
                      allowScalar:NO
 | 
			
		||||
                            error:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark Parsing
 | 
			
		||||
 | 
			
		||||
- (id)objectWithString:(NSString *)repr {
 | 
			
		||||
    id obj = [jsonParser objectWithString:repr];
 | 
			
		||||
    if (obj)
 | 
			
		||||
        return obj;
 | 
			
		||||
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    errorTrace = [[jsonParser errorTrace] mutableCopy];
 | 
			
		||||
    
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns the object represented by the passed-in string or nil on error. The returned object can be
 | 
			
		||||
 a string, number, boolean, null, array or dictionary.
 | 
			
		||||
 
 | 
			
		||||
 @param value the json string to parse
 | 
			
		||||
 @param allowScalar whether to return objects for JSON fragments
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 
 | 
			
		||||
 @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
 | 
			
		||||
 */
 | 
			
		||||
- (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
 | 
			
		||||
 | 
			
		||||
    id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value];
 | 
			
		||||
    if (obj)
 | 
			
		||||
        return obj;
 | 
			
		||||
    
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    errorTrace = [[jsonParser errorTrace] mutableCopy];
 | 
			
		||||
 | 
			
		||||
    if (error)
 | 
			
		||||
        *error = [errorTrace lastObject];
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns the object represented by the passed-in string or nil on error. The returned object can be
 | 
			
		||||
 a string, number, boolean, null, array or dictionary.
 | 
			
		||||
 
 | 
			
		||||
 @param repr the json string to parse
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 
 | 
			
		||||
 @deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed. 
 | 
			
		||||
 */
 | 
			
		||||
- (id)fragmentWithString:(NSString*)repr error:(NSError**)error {
 | 
			
		||||
    return [self objectWithString:repr
 | 
			
		||||
                      allowScalar:YES
 | 
			
		||||
                            error:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 Returns the object represented by the passed-in string or nil on error. The returned object
 | 
			
		||||
 will be either a dictionary or an array.
 | 
			
		||||
 
 | 
			
		||||
 @param repr the json string to parse
 | 
			
		||||
 @param error used to return an error by reference (pass NULL if this is not desired)
 | 
			
		||||
 */
 | 
			
		||||
- (id)objectWithString:(NSString*)repr error:(NSError**)error {
 | 
			
		||||
    return [self objectWithString:repr
 | 
			
		||||
                      allowScalar:NO
 | 
			
		||||
                            error:error];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma mark Properties - parsing
 | 
			
		||||
 | 
			
		||||
- (unsigned int)maxDepth {
 | 
			
		||||
    return [jsonParser maxDepth];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setMaxDepth:(unsigned int)d {
 | 
			
		||||
	[jsonWriter setMaxDepth:d];
 | 
			
		||||
	[jsonParser setMaxDepth:d];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#pragma mark Properties - writing
 | 
			
		||||
 | 
			
		||||
- (BOOL)humanReadable {
 | 
			
		||||
    return jsonWriter.humanReadable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setHumanReadable:(BOOL)x {
 | 
			
		||||
    jsonWriter.humanReadable = x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)sortKeys {
 | 
			
		||||
    return jsonWriter.sortKeys;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setSortKeys:(BOOL)x {
 | 
			
		||||
    jsonWriter.sortKeys = x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,87 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
extern NSString * SBJSONErrorDomain;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    EUNSUPPORTED = 1,
 | 
			
		||||
    EPARSENUM,
 | 
			
		||||
    EPARSE,
 | 
			
		||||
    EFRAGMENT,
 | 
			
		||||
    ECTRL,
 | 
			
		||||
    EUNICODE,
 | 
			
		||||
    EDEPTH,
 | 
			
		||||
    EESCAPE,
 | 
			
		||||
    ETRAILCOMMA,
 | 
			
		||||
    ETRAILGARBAGE,
 | 
			
		||||
    EEOF,
 | 
			
		||||
    EINPUT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Common base class for parsing & writing.
 | 
			
		||||
 | 
			
		||||
 This class contains the common error-handling code and option between the parser/writer.
 | 
			
		||||
 */
 | 
			
		||||
@interface SBJsonBase : NSObject {
 | 
			
		||||
    NSMutableArray *errorTrace;
 | 
			
		||||
 | 
			
		||||
@protected
 | 
			
		||||
    unsigned int depth, maxDepth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief The maximum recursing depth.
 | 
			
		||||
 
 | 
			
		||||
 Defaults to 512. If the input is nested deeper than this the input will be deemed to be
 | 
			
		||||
 malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
 | 
			
		||||
 turn off this security feature by setting the maxDepth value to 0.
 | 
			
		||||
 */
 | 
			
		||||
- (void)setMaxDepth:(unsigned int)theDepth;
 | 
			
		||||
- (unsigned int)maxDepth;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Return an error trace, or nil if there was no errors.
 | 
			
		||||
 
 | 
			
		||||
 Note that this method returns the trace of the last method that failed.
 | 
			
		||||
 You need to check the return value of the call you're making to figure out
 | 
			
		||||
 if the call actually failed, before you know call this method.
 | 
			
		||||
 */
 | 
			
		||||
- (NSArray *)errorTrace;
 | 
			
		||||
 | 
			
		||||
/// @internal for use in subclasses to add errors to the stack trace
 | 
			
		||||
- (void)addErrorWithCode:(unsigned int)code description:(NSString*)str;
 | 
			
		||||
 | 
			
		||||
/// @internal for use in subclasess to clear the error before a new parsing attempt
 | 
			
		||||
- (void)clearErrorTrace;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,84 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "SBJsonBase.h"
 | 
			
		||||
NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation SBJsonBase
 | 
			
		||||
- (id)init {
 | 
			
		||||
    self = [super init];
 | 
			
		||||
    if (self)
 | 
			
		||||
        maxDepth = 512;
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    [super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setMaxDepth:(unsigned int)theDepth {
 | 
			
		||||
	maxDepth = theDepth;
 | 
			
		||||
}
 | 
			
		||||
- (unsigned int)maxDepth {
 | 
			
		||||
	return maxDepth;
 | 
			
		||||
}
 | 
			
		||||
- (NSArray *)errorTrace {
 | 
			
		||||
	return errorTrace;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)addErrorWithCode:(unsigned int)code description:(NSString*)str {
 | 
			
		||||
    NSDictionary *userInfo;
 | 
			
		||||
    if (!errorTrace) {
 | 
			
		||||
        errorTrace = [NSMutableArray new];
 | 
			
		||||
        userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey];
 | 
			
		||||
        
 | 
			
		||||
    } else {
 | 
			
		||||
        userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
                    str, NSLocalizedDescriptionKey,
 | 
			
		||||
                    [errorTrace lastObject], NSUnderlyingErrorKey,
 | 
			
		||||
                    nil];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo];
 | 
			
		||||
 | 
			
		||||
    [self willChangeValueForKey:@"errorTrace"];
 | 
			
		||||
    [errorTrace addObject:error];
 | 
			
		||||
    [self didChangeValueForKey:@"errorTrace"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)clearErrorTrace {
 | 
			
		||||
    [self willChangeValueForKey:@"errorTrace"];
 | 
			
		||||
    [errorTrace release];
 | 
			
		||||
    errorTrace = nil;
 | 
			
		||||
    [self didChangeValueForKey:@"errorTrace"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,87 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "SBJsonBase.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  @brief Options for the parser class.
 | 
			
		||||
 
 | 
			
		||||
 This exists so the SBJSON facade can implement the options in the parser without having to re-declare them.
 | 
			
		||||
 */
 | 
			
		||||
@protocol SBJsonParser
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Return the object represented by the given string.
 | 
			
		||||
 
 | 
			
		||||
 Returns the object represented by the passed-in string or nil on error. The returned object can be
 | 
			
		||||
 a string, number, boolean, null, array or dictionary.
 | 
			
		||||
 
 | 
			
		||||
 @param repr the json string to parse
 | 
			
		||||
 */
 | 
			
		||||
- (id)objectWithString:(NSString *)repr;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief The JSON parser class.
 | 
			
		||||
 
 | 
			
		||||
 JSON is mapped to Objective-C types in the following way:
 | 
			
		||||
 
 | 
			
		||||
 @li Null -> NSNull
 | 
			
		||||
 @li String -> NSMutableString
 | 
			
		||||
 @li Array -> NSMutableArray
 | 
			
		||||
 @li Object -> NSMutableDictionary
 | 
			
		||||
 @li Boolean -> NSNumber (initialised with -initWithBool:)
 | 
			
		||||
 @li Number -> NSDecimalNumber
 | 
			
		||||
 
 | 
			
		||||
 Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber
 | 
			
		||||
 instances. These are initialised with the -initWithBool: method, and 
 | 
			
		||||
 round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be
 | 
			
		||||
 represented as 'true' and 'false' again.)
 | 
			
		||||
 
 | 
			
		||||
 JSON numbers turn into NSDecimalNumber instances,
 | 
			
		||||
 as we can thus avoid any loss of precision. (JSON allows ridiculously large numbers.)
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
@interface SBJsonParser : SBJsonBase <SBJsonParser> {
 | 
			
		||||
    
 | 
			
		||||
@private
 | 
			
		||||
    const char *c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// don't use - exists for backwards compatibility with 2.1.x only. Will be removed in 2.3.
 | 
			
		||||
@interface SBJsonParser (Private)
 | 
			
		||||
- (id)fragmentWithString:(id)repr;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,475 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "SBJsonParser.h"
 | 
			
		||||
 | 
			
		||||
@interface SBJsonParser ()
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanValue:(NSObject **)o;
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o;
 | 
			
		||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
 | 
			
		||||
- (BOOL)scanRestOfNull:(NSNull **)o;
 | 
			
		||||
- (BOOL)scanRestOfFalse:(NSNumber **)o;
 | 
			
		||||
- (BOOL)scanRestOfTrue:(NSNumber **)o;
 | 
			
		||||
- (BOOL)scanRestOfString:(NSMutableString **)o;
 | 
			
		||||
 | 
			
		||||
// Cannot manage without looking at the first digit
 | 
			
		||||
- (BOOL)scanNumber:(NSNumber **)o;
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanHexQuad:(unichar *)x;
 | 
			
		||||
- (BOOL)scanUnicodeChar:(unichar *)x;
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanIsAtEnd;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#define skipWhitespace(c) while (isspace(*c)) c++
 | 
			
		||||
#define skipDigits(c) while (isdigit(*c)) c++
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation SBJsonParser
 | 
			
		||||
 | 
			
		||||
static char ctrl[0x22];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
+ (void)initialize {
 | 
			
		||||
    ctrl[0] = '\"';
 | 
			
		||||
    ctrl[1] = '\\';
 | 
			
		||||
    for (int i = 1; i < 0x20; i++)
 | 
			
		||||
        ctrl[i+1] = i;
 | 
			
		||||
    ctrl[0x21] = 0;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @deprecated This exists in order to provide fragment support in older APIs in one more version.
 | 
			
		||||
 It should be removed in the next major version.
 | 
			
		||||
 */
 | 
			
		||||
- (id)fragmentWithString:(id)repr {
 | 
			
		||||
    [self clearErrorTrace];
 | 
			
		||||
    
 | 
			
		||||
    if (!repr) {
 | 
			
		||||
        [self addErrorWithCode:EINPUT description:@"Input was 'nil'"];
 | 
			
		||||
        return nil;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    depth = 0;
 | 
			
		||||
    c = [repr UTF8String];
 | 
			
		||||
    
 | 
			
		||||
    id o;
 | 
			
		||||
    if (![self scanValue:&o]) {
 | 
			
		||||
        return nil;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // We found some valid JSON. But did it also contain something else?
 | 
			
		||||
    if (![self scanIsAtEnd]) {
 | 
			
		||||
        [self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"];
 | 
			
		||||
        return nil;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    NSAssert1(o, @"Should have a valid object from %@", repr);
 | 
			
		||||
    return o;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)objectWithString:(NSString *)repr {
 | 
			
		||||
 | 
			
		||||
    id o = [self fragmentWithString:repr];
 | 
			
		||||
    if (!o)
 | 
			
		||||
        return nil;
 | 
			
		||||
    
 | 
			
		||||
    // Check that the object we've found is a valid JSON container.
 | 
			
		||||
    if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) {
 | 
			
		||||
        [self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"];
 | 
			
		||||
        return nil;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 In contrast to the public methods, it is an error to omit the error parameter here.
 | 
			
		||||
 */
 | 
			
		||||
- (BOOL)scanValue:(NSObject **)o
 | 
			
		||||
{
 | 
			
		||||
    skipWhitespace(c);
 | 
			
		||||
    
 | 
			
		||||
    switch (*c++) {
 | 
			
		||||
        case '{':
 | 
			
		||||
            return [self scanRestOfDictionary:(NSMutableDictionary **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case '[':
 | 
			
		||||
            return [self scanRestOfArray:(NSMutableArray **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case '"':
 | 
			
		||||
            return [self scanRestOfString:(NSMutableString **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case 'f':
 | 
			
		||||
            return [self scanRestOfFalse:(NSNumber **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case 't':
 | 
			
		||||
            return [self scanRestOfTrue:(NSNumber **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case 'n':
 | 
			
		||||
            return [self scanRestOfNull:(NSNull **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case '-':
 | 
			
		||||
        case '0'...'9':
 | 
			
		||||
            c--; // cannot verify number correctly without the first character
 | 
			
		||||
            return [self scanNumber:(NSNumber **)o];
 | 
			
		||||
            break;
 | 
			
		||||
        case '+':
 | 
			
		||||
            [self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"];
 | 
			
		||||
            return NO;
 | 
			
		||||
            break;
 | 
			
		||||
        case 0x0:
 | 
			
		||||
            [self addErrorWithCode:EEOF description:@"Unexpected end of string"];
 | 
			
		||||
            return NO;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            [self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
 | 
			
		||||
            return NO;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    NSAssert(0, @"Should never get here");
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfTrue:(NSNumber **)o
 | 
			
		||||
{
 | 
			
		||||
    if (!strncmp(c, "rue", 3)) {
 | 
			
		||||
        c += 3;
 | 
			
		||||
        *o = [NSNumber numberWithBool:YES];
 | 
			
		||||
        return YES;
 | 
			
		||||
    }
 | 
			
		||||
    [self addErrorWithCode:EPARSE description:@"Expected 'true'"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfFalse:(NSNumber **)o
 | 
			
		||||
{
 | 
			
		||||
    if (!strncmp(c, "alse", 4)) {
 | 
			
		||||
        c += 4;
 | 
			
		||||
        *o = [NSNumber numberWithBool:NO];
 | 
			
		||||
        return YES;
 | 
			
		||||
    }
 | 
			
		||||
    [self addErrorWithCode:EPARSE description: @"Expected 'false'"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfNull:(NSNull **)o {
 | 
			
		||||
    if (!strncmp(c, "ull", 3)) {
 | 
			
		||||
        c += 3;
 | 
			
		||||
        *o = [NSNull null];
 | 
			
		||||
        return YES;
 | 
			
		||||
    }
 | 
			
		||||
    [self addErrorWithCode:EPARSE description: @"Expected 'null'"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o {
 | 
			
		||||
    if (maxDepth && ++depth > maxDepth) {
 | 
			
		||||
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 | 
			
		||||
        return NO;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    *o = [NSMutableArray arrayWithCapacity:8];
 | 
			
		||||
    
 | 
			
		||||
    for (; *c ;) {
 | 
			
		||||
        id v;
 | 
			
		||||
        
 | 
			
		||||
        skipWhitespace(c);
 | 
			
		||||
        if (*c == ']' && c++) {
 | 
			
		||||
            depth--;
 | 
			
		||||
            return YES;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (![self scanValue:&v]) {
 | 
			
		||||
            [self addErrorWithCode:EPARSE description:@"Expected value while parsing array"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [*o addObject:v];
 | 
			
		||||
        
 | 
			
		||||
        skipWhitespace(c);
 | 
			
		||||
        if (*c == ',' && c++) {
 | 
			
		||||
            skipWhitespace(c);
 | 
			
		||||
            if (*c == ']') {
 | 
			
		||||
                [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"];
 | 
			
		||||
                return NO;
 | 
			
		||||
            }
 | 
			
		||||
        }        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    [self addErrorWithCode:EEOF description: @"End of input while parsing array"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o 
 | 
			
		||||
{
 | 
			
		||||
    if (maxDepth && ++depth > maxDepth) {
 | 
			
		||||
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 | 
			
		||||
        return NO;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    *o = [NSMutableDictionary dictionaryWithCapacity:7];
 | 
			
		||||
    
 | 
			
		||||
    for (; *c ;) {
 | 
			
		||||
        id k, v;
 | 
			
		||||
        
 | 
			
		||||
        skipWhitespace(c);
 | 
			
		||||
        if (*c == '}' && c++) {
 | 
			
		||||
            depth--;
 | 
			
		||||
            return YES;
 | 
			
		||||
        }    
 | 
			
		||||
        
 | 
			
		||||
        if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) {
 | 
			
		||||
            [self addErrorWithCode:EPARSE description: @"Object key string expected"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        skipWhitespace(c);
 | 
			
		||||
        if (*c != ':') {
 | 
			
		||||
            [self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        c++;
 | 
			
		||||
        if (![self scanValue:&v]) {
 | 
			
		||||
            NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k];
 | 
			
		||||
            [self addErrorWithCode:EPARSE description: string];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [*o setObject:v forKey:k];
 | 
			
		||||
        
 | 
			
		||||
        skipWhitespace(c);
 | 
			
		||||
        if (*c == ',' && c++) {
 | 
			
		||||
            skipWhitespace(c);
 | 
			
		||||
            if (*c == '}') {
 | 
			
		||||
                [self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"];
 | 
			
		||||
                return NO;
 | 
			
		||||
            }
 | 
			
		||||
        }        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    [self addErrorWithCode:EEOF description: @"End of input while parsing object"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanRestOfString:(NSMutableString **)o 
 | 
			
		||||
{
 | 
			
		||||
    *o = [NSMutableString stringWithCapacity:16];
 | 
			
		||||
    do {
 | 
			
		||||
        // First see if there's a portion we can grab in one go. 
 | 
			
		||||
        // Doing this caused a massive speedup on the long string.
 | 
			
		||||
        size_t len = strcspn(c, ctrl);
 | 
			
		||||
        if (len) {
 | 
			
		||||
            // check for 
 | 
			
		||||
            id t = [[NSString alloc] initWithBytesNoCopy:(char*)c
 | 
			
		||||
                                                  length:len
 | 
			
		||||
                                                encoding:NSUTF8StringEncoding
 | 
			
		||||
                                            freeWhenDone:NO];
 | 
			
		||||
            if (t) {
 | 
			
		||||
                [*o appendString:t];
 | 
			
		||||
                [t release];
 | 
			
		||||
                c += len;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (*c == '"') {
 | 
			
		||||
            c++;
 | 
			
		||||
            return YES;
 | 
			
		||||
            
 | 
			
		||||
        } else if (*c == '\\') {
 | 
			
		||||
            unichar uc = *++c;
 | 
			
		||||
            switch (uc) {
 | 
			
		||||
                case '\\':
 | 
			
		||||
                case '/':
 | 
			
		||||
                case '"':
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
                case 'b':   uc = '\b';  break;
 | 
			
		||||
                case 'n':   uc = '\n';  break;
 | 
			
		||||
                case 'r':   uc = '\r';  break;
 | 
			
		||||
                case 't':   uc = '\t';  break;
 | 
			
		||||
                case 'f':   uc = '\f';  break;                    
 | 
			
		||||
                    
 | 
			
		||||
                case 'u':
 | 
			
		||||
                    c++;
 | 
			
		||||
                    if (![self scanUnicodeChar:&uc]) {
 | 
			
		||||
                        [self addErrorWithCode:EUNICODE description: @"Broken unicode character"];
 | 
			
		||||
                        return NO;
 | 
			
		||||
                    }
 | 
			
		||||
                    c--; // hack.
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    [self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]];
 | 
			
		||||
                    return NO;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1);
 | 
			
		||||
            c++;
 | 
			
		||||
            
 | 
			
		||||
        } else if (*c < 0x20) {
 | 
			
		||||
            [self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]];
 | 
			
		||||
            return NO;
 | 
			
		||||
            
 | 
			
		||||
        } else {
 | 
			
		||||
            NSLog(@"should not be able to get here");
 | 
			
		||||
        }
 | 
			
		||||
    } while (*c);
 | 
			
		||||
    
 | 
			
		||||
    [self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanUnicodeChar:(unichar *)x
 | 
			
		||||
{
 | 
			
		||||
    unichar hi, lo;
 | 
			
		||||
    
 | 
			
		||||
    if (![self scanHexQuad:&hi]) {
 | 
			
		||||
        [self addErrorWithCode:EUNICODE description: @"Missing hex quad"];
 | 
			
		||||
        return NO;        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (hi >= 0xd800) {     // high surrogate char?
 | 
			
		||||
        if (hi < 0xdc00) {  // yes - expect a low char
 | 
			
		||||
            
 | 
			
		||||
            if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) {
 | 
			
		||||
                [self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"];
 | 
			
		||||
                return NO;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            if (lo < 0xdc00 || lo >= 0xdfff) {
 | 
			
		||||
                [self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"];
 | 
			
		||||
                return NO;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000;
 | 
			
		||||
            
 | 
			
		||||
        } else if (hi < 0xe000) {
 | 
			
		||||
            [self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    *x = hi;
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanHexQuad:(unichar *)x
 | 
			
		||||
{
 | 
			
		||||
    *x = 0;
 | 
			
		||||
    for (int i = 0; i < 4; i++) {
 | 
			
		||||
        unichar uc = *c;
 | 
			
		||||
        c++;
 | 
			
		||||
        int d = (uc >= '0' && uc <= '9')
 | 
			
		||||
        ? uc - '0' : (uc >= 'a' && uc <= 'f')
 | 
			
		||||
        ? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
 | 
			
		||||
        ? (uc - 'A' + 10) : -1;
 | 
			
		||||
        if (d == -1) {
 | 
			
		||||
            [self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        *x *= 16;
 | 
			
		||||
        *x += d;
 | 
			
		||||
    }
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanNumber:(NSNumber **)o
 | 
			
		||||
{
 | 
			
		||||
    const char *ns = c;
 | 
			
		||||
    
 | 
			
		||||
    // The logic to test for validity of the number formatting is relicensed
 | 
			
		||||
    // from JSON::XS with permission from its author Marc Lehmann.
 | 
			
		||||
    // (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .)
 | 
			
		||||
    
 | 
			
		||||
    if ('-' == *c)
 | 
			
		||||
        c++;
 | 
			
		||||
    
 | 
			
		||||
    if ('0' == *c && c++) {        
 | 
			
		||||
        if (isdigit(*c)) {
 | 
			
		||||
            [self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
    } else if (!isdigit(*c) && c != ns) {
 | 
			
		||||
        [self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"];
 | 
			
		||||
        return NO;
 | 
			
		||||
        
 | 
			
		||||
    } else {
 | 
			
		||||
        skipDigits(c);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Fractional part
 | 
			
		||||
    if ('.' == *c && c++) {
 | 
			
		||||
        
 | 
			
		||||
        if (!isdigit(*c)) {
 | 
			
		||||
            [self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }        
 | 
			
		||||
        skipDigits(c);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Exponential part
 | 
			
		||||
    if ('e' == *c || 'E' == *c) {
 | 
			
		||||
        c++;
 | 
			
		||||
        
 | 
			
		||||
        if ('-' == *c || '+' == *c)
 | 
			
		||||
            c++;
 | 
			
		||||
        
 | 
			
		||||
        if (!isdigit(*c)) {
 | 
			
		||||
            [self addErrorWithCode:EPARSENUM description: @"No digits after exponent"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        skipDigits(c);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
 | 
			
		||||
                                            length:c - ns
 | 
			
		||||
                                          encoding:NSUTF8StringEncoding
 | 
			
		||||
                                      freeWhenDone:NO];
 | 
			
		||||
    [str autorelease];
 | 
			
		||||
    if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
 | 
			
		||||
        return YES;
 | 
			
		||||
    
 | 
			
		||||
    [self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"];
 | 
			
		||||
    return NO;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)scanIsAtEnd
 | 
			
		||||
{
 | 
			
		||||
    skipWhitespace(c);
 | 
			
		||||
    return !*c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,131 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "SBJsonBase.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Options for the writer class.
 | 
			
		||||
 
 | 
			
		||||
 This exists so the SBJSON facade can implement the options in the writer without having to re-declare them.
 | 
			
		||||
 */
 | 
			
		||||
@protocol SBJsonWriter
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Whether we are generating human-readable (multiline) JSON.
 | 
			
		||||
 
 | 
			
		||||
 Set whether or not to generate human-readable JSON. The default is NO, which produces
 | 
			
		||||
 JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
 | 
			
		||||
 JSON with linebreaks after each array value and dictionary key/value pair, indented two
 | 
			
		||||
 spaces per nesting level.
 | 
			
		||||
 */
 | 
			
		||||
- (void)setHumanReadable:(BOOL)isHumanReadable;
 | 
			
		||||
- (BOOL)humanReadable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Whether or not to sort the dictionary keys in the output.
 | 
			
		||||
 
 | 
			
		||||
 If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
 | 
			
		||||
 (This is useful if you need to compare two structures, for example.) The default is NO.
 | 
			
		||||
 */
 | 
			
		||||
- (void)setSortKeys:(BOOL)willShortKeys;
 | 
			
		||||
- (BOOL)sortKeys;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Return JSON representation (or fragment) for the given object.
 | 
			
		||||
 
 | 
			
		||||
 Returns a string containing JSON representation of the passed in value, or nil on error.
 | 
			
		||||
 If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
 | 
			
		||||
 
 | 
			
		||||
 @param value any instance that can be represented as a JSON fragment
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
- (NSString*)stringWithObject:(id)value;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief The JSON writer class.
 | 
			
		||||
 
 | 
			
		||||
 Objective-C types are mapped to JSON types in the following way:
 | 
			
		||||
 
 | 
			
		||||
 @li NSNull -> Null
 | 
			
		||||
 @li NSString -> String
 | 
			
		||||
 @li NSArray -> Array
 | 
			
		||||
 @li NSDictionary -> Object
 | 
			
		||||
 @li NSNumber (-initWithBool:) -> Boolean
 | 
			
		||||
 @li NSNumber -> Number
 | 
			
		||||
 
 | 
			
		||||
 In JSON the keys of an object must be strings. NSDictionary keys need
 | 
			
		||||
 not be, but attempting to convert an NSDictionary with non-string keys
 | 
			
		||||
 into JSON will throw an exception.
 | 
			
		||||
 
 | 
			
		||||
 NSNumber instances created with the +initWithBool: method are
 | 
			
		||||
 converted into the JSON boolean "true" and "false" values, and vice
 | 
			
		||||
 versa. Any other NSNumber instances are converted to a JSON number the
 | 
			
		||||
 way you would expect.
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
@interface SBJsonWriter : SBJsonBase <SBJsonWriter> {
 | 
			
		||||
 | 
			
		||||
@private
 | 
			
		||||
    BOOL sortKeys, humanReadable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
// don't use - exists for backwards compatibility. Will be removed in 2.3.
 | 
			
		||||
@interface SBJsonWriter (Private)
 | 
			
		||||
- (NSString*)stringWithFragment:(id)value;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @brief Allows generation of JSON for otherwise unsupported classes.
 | 
			
		||||
 
 | 
			
		||||
 If you have a custom class that you want to create a JSON representation for you can implement
 | 
			
		||||
 this method in your class. It should return a representation of your object defined
 | 
			
		||||
 in terms of objects that can be translated into JSON. For example, a Person
 | 
			
		||||
 object might implement it like this:
 | 
			
		||||
 
 | 
			
		||||
 @code
 | 
			
		||||
 - (id)jsonProxyObject {
 | 
			
		||||
    return [NSDictionary dictionaryWithObjectsAndKeys:
 | 
			
		||||
        name, @"name",
 | 
			
		||||
        phone, @"phone",
 | 
			
		||||
        email, @"email",
 | 
			
		||||
        nil];
 | 
			
		||||
 }
 | 
			
		||||
 @endcode
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
@interface NSObject (SBProxyForJson)
 | 
			
		||||
- (id)proxyForJson;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@ -1,248 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (C) 2009 Stig Brautaset. All rights reserved.
 | 
			
		||||
 
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions of source code must retain the above copyright notice, this
 | 
			
		||||
   list of conditions and the following disclaimer.
 | 
			
		||||
 
 | 
			
		||||
 * Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
   this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
   and/or other materials provided with the distribution.
 | 
			
		||||
 
 | 
			
		||||
 * Neither the name of the author nor the names of its contributors may be used
 | 
			
		||||
   to endorse or promote products derived from this software without specific
 | 
			
		||||
   prior written permission.
 | 
			
		||||
 
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#import "SBJsonWriter.h"
 | 
			
		||||
 | 
			
		||||
@interface SBJsonWriter ()
 | 
			
		||||
 | 
			
		||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json;
 | 
			
		||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json;
 | 
			
		||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json;
 | 
			
		||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json;
 | 
			
		||||
 | 
			
		||||
- (NSString*)indent;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation SBJsonWriter
 | 
			
		||||
 | 
			
		||||
static NSMutableCharacterSet *kEscapeChars;
 | 
			
		||||
 | 
			
		||||
+ (void)initialize {
 | 
			
		||||
	kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain];
 | 
			
		||||
	[kEscapeChars addCharactersInString: @"\"\\"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setHumanReadable:(BOOL)isHumanReadable {
 | 
			
		||||
	humanReadable = isHumanReadable;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)humanReadable {
 | 
			
		||||
	return humanReadable;
 | 
			
		||||
}
 | 
			
		||||
- (void)setSortKeys:(BOOL)willShortKeys {
 | 
			
		||||
	sortKeys = willShortKeys;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)sortKeys {
 | 
			
		||||
	return sortKeys;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 @deprecated This exists in order to provide fragment support in older APIs in one more version.
 | 
			
		||||
 It should be removed in the next major version.
 | 
			
		||||
 */
 | 
			
		||||
- (NSString*)stringWithFragment:(id)value {
 | 
			
		||||
    [self clearErrorTrace];
 | 
			
		||||
    depth = 0;
 | 
			
		||||
    NSMutableString *json = [NSMutableString stringWithCapacity:128];
 | 
			
		||||
    
 | 
			
		||||
    if ([self appendValue:value into:json])
 | 
			
		||||
        return json;
 | 
			
		||||
    
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (NSString*)stringWithObject:(id)value {
 | 
			
		||||
    
 | 
			
		||||
    if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
 | 
			
		||||
        return [self stringWithFragment:value];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ([value respondsToSelector:@selector(proxyForJson)]) {
 | 
			
		||||
        NSString *tmp = [self stringWithObject:[value proxyForJson]];
 | 
			
		||||
        if (tmp)
 | 
			
		||||
            return tmp;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    [self clearErrorTrace];
 | 
			
		||||
    [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"];
 | 
			
		||||
    return nil;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- (NSString*)indent {
 | 
			
		||||
    return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json {
 | 
			
		||||
    if ([fragment isKindOfClass:[NSDictionary class]]) {
 | 
			
		||||
        if (![self appendDictionary:fragment into:json])
 | 
			
		||||
            return NO;
 | 
			
		||||
        
 | 
			
		||||
    } else if ([fragment isKindOfClass:[NSArray class]]) {
 | 
			
		||||
        if (![self appendArray:fragment into:json])
 | 
			
		||||
            return NO;
 | 
			
		||||
        
 | 
			
		||||
    } else if ([fragment isKindOfClass:[NSString class]]) {
 | 
			
		||||
        if (![self appendString:fragment into:json])
 | 
			
		||||
            return NO;
 | 
			
		||||
        
 | 
			
		||||
    } else if ([fragment isKindOfClass:[NSNumber class]]) {
 | 
			
		||||
        if ('c' == *[fragment objCType])
 | 
			
		||||
            [json appendString:[fragment boolValue] ? @"true" : @"false"];
 | 
			
		||||
        else
 | 
			
		||||
            [json appendString:[fragment stringValue]];
 | 
			
		||||
        
 | 
			
		||||
    } else if ([fragment isKindOfClass:[NSNull class]]) {
 | 
			
		||||
        [json appendString:@"null"];
 | 
			
		||||
    } else if ([fragment respondsToSelector:@selector(proxyForJson)]) {
 | 
			
		||||
        [self appendValue:[fragment proxyForJson] into:json];
 | 
			
		||||
        
 | 
			
		||||
    } else {
 | 
			
		||||
        [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]];
 | 
			
		||||
        return NO;
 | 
			
		||||
    }
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json {
 | 
			
		||||
    if (maxDepth && ++depth > maxDepth) {
 | 
			
		||||
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 | 
			
		||||
        return NO;
 | 
			
		||||
    }
 | 
			
		||||
    [json appendString:@"["];
 | 
			
		||||
    
 | 
			
		||||
    BOOL addComma = NO;    
 | 
			
		||||
    for (int i=0; i<[fragment count]; i++) {
 | 
			
		||||
		id value = [fragment objectAtIndex:i];
 | 
			
		||||
        if (addComma)
 | 
			
		||||
            [json appendString:@","];
 | 
			
		||||
        else
 | 
			
		||||
            addComma = YES;
 | 
			
		||||
        
 | 
			
		||||
        if ([self humanReadable])
 | 
			
		||||
            [json appendString:[self indent]];
 | 
			
		||||
        
 | 
			
		||||
        if (![self appendValue:value into:json]) {
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    depth--;
 | 
			
		||||
    if ([self humanReadable] && [fragment count])
 | 
			
		||||
        [json appendString:[self indent]];
 | 
			
		||||
    [json appendString:@"]"];
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json {
 | 
			
		||||
    if (maxDepth && ++depth > maxDepth) {
 | 
			
		||||
        [self addErrorWithCode:EDEPTH description: @"Nested too deep"];
 | 
			
		||||
        return NO;
 | 
			
		||||
    }
 | 
			
		||||
    [json appendString:@"{"];
 | 
			
		||||
    
 | 
			
		||||
    NSString *colon = [self humanReadable] ? @" : " : @":";
 | 
			
		||||
    BOOL addComma = NO;
 | 
			
		||||
    NSArray *keys = [fragment allKeys];
 | 
			
		||||
    if (sortKeys)
 | 
			
		||||
        keys = [keys sortedArrayUsingSelector:@selector(compare:)];
 | 
			
		||||
    
 | 
			
		||||
    for (int i=0; i<[keys count]; i++) {
 | 
			
		||||
		id value = [keys objectAtIndex:i];
 | 
			
		||||
        if (addComma)
 | 
			
		||||
            [json appendString:@","];
 | 
			
		||||
        else
 | 
			
		||||
            addComma = YES;
 | 
			
		||||
        
 | 
			
		||||
        if ([self humanReadable])
 | 
			
		||||
            [json appendString:[self indent]];
 | 
			
		||||
        
 | 
			
		||||
        if (![value isKindOfClass:[NSString class]]) {
 | 
			
		||||
            [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (![self appendString:value into:json])
 | 
			
		||||
            return NO;
 | 
			
		||||
        
 | 
			
		||||
        [json appendString:colon];
 | 
			
		||||
        if (![self appendValue:[fragment objectForKey:value] into:json]) {
 | 
			
		||||
            [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]];
 | 
			
		||||
            return NO;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    depth--;
 | 
			
		||||
    if ([self humanReadable] && [fragment count])
 | 
			
		||||
        [json appendString:[self indent]];
 | 
			
		||||
    [json appendString:@"}"];
 | 
			
		||||
    return YES;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json {
 | 
			
		||||
    
 | 
			
		||||
    [json appendString:@"\""];
 | 
			
		||||
    
 | 
			
		||||
    NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars];
 | 
			
		||||
    if ( !esc.length ) {
 | 
			
		||||
        // No special chars -- can just add the raw string:
 | 
			
		||||
        [json appendString:fragment];
 | 
			
		||||
        
 | 
			
		||||
    } else {
 | 
			
		||||
        unsigned int length = [fragment length];
 | 
			
		||||
        for (unsigned int i = 0; i < length; i++) {
 | 
			
		||||
            unichar uc = [fragment characterAtIndex:i];
 | 
			
		||||
            switch (uc) {
 | 
			
		||||
                case '"':   [json appendString:@"\\\""];       break;
 | 
			
		||||
                case '\\':  [json appendString:@"\\\\"];       break;
 | 
			
		||||
                case '\t':  [json appendString:@"\\t"];        break;
 | 
			
		||||
                case '\n':  [json appendString:@"\\n"];        break;
 | 
			
		||||
                case '\r':  [json appendString:@"\\r"];        break;
 | 
			
		||||
                case '\b':  [json appendString:@"\\b"];        break;
 | 
			
		||||
                case '\f':  [json appendString:@"\\f"];        break;
 | 
			
		||||
                default:    
 | 
			
		||||
                    if (uc < 0x20) {
 | 
			
		||||
                        [json appendFormat:@"\\u%04x", uc];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                    
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    [json appendString:@"\""];
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,230 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Base64Transcoder.c
 | 
			
		||||
 *  Base64Test
 | 
			
		||||
 *
 | 
			
		||||
 *  Created by Jonathan Wight on Tue Mar 18 2003.
 | 
			
		||||
 *  Copyright (c) 2003 Toxic Software. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 *  of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 *  in the Software without restriction, including without limitation the rights
 | 
			
		||||
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 *  copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 *  furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 *  The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 *  all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 *  THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Base64Transcoder.h"
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
const u_int8_t kBase64EncodeTable[64] = {
 | 
			
		||||
	/*  0 */ 'A',	/*  1 */ 'B',	/*  2 */ 'C',	/*  3 */ 'D', 
 | 
			
		||||
	/*  4 */ 'E',	/*  5 */ 'F',	/*  6 */ 'G',	/*  7 */ 'H', 
 | 
			
		||||
	/*  8 */ 'I',	/*  9 */ 'J',	/* 10 */ 'K',	/* 11 */ 'L', 
 | 
			
		||||
	/* 12 */ 'M',	/* 13 */ 'N',	/* 14 */ 'O',	/* 15 */ 'P', 
 | 
			
		||||
	/* 16 */ 'Q',	/* 17 */ 'R',	/* 18 */ 'S',	/* 19 */ 'T', 
 | 
			
		||||
	/* 20 */ 'U',	/* 21 */ 'V',	/* 22 */ 'W',	/* 23 */ 'X', 
 | 
			
		||||
	/* 24 */ 'Y',	/* 25 */ 'Z',	/* 26 */ 'a',	/* 27 */ 'b', 
 | 
			
		||||
	/* 28 */ 'c',	/* 29 */ 'd',	/* 30 */ 'e',	/* 31 */ 'f', 
 | 
			
		||||
	/* 32 */ 'g',	/* 33 */ 'h',	/* 34 */ 'i',	/* 35 */ 'j', 
 | 
			
		||||
	/* 36 */ 'k',	/* 37 */ 'l',	/* 38 */ 'm',	/* 39 */ 'n', 
 | 
			
		||||
	/* 40 */ 'o',	/* 41 */ 'p',	/* 42 */ 'q',	/* 43 */ 'r', 
 | 
			
		||||
	/* 44 */ 's',	/* 45 */ 't',	/* 46 */ 'u',	/* 47 */ 'v', 
 | 
			
		||||
	/* 48 */ 'w',	/* 49 */ 'x',	/* 50 */ 'y',	/* 51 */ 'z', 
 | 
			
		||||
	/* 52 */ '0',	/* 53 */ '1',	/* 54 */ '2',	/* 55 */ '3', 
 | 
			
		||||
	/* 56 */ '4',	/* 57 */ '5',	/* 58 */ '6',	/* 59 */ '7', 
 | 
			
		||||
	/* 60 */ '8',	/* 61 */ '9',	/* 62 */ '+',	/* 63 */ '/'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
-1 = Base64 end of data marker.
 | 
			
		||||
-2 = White space (tabs, cr, lf, space)
 | 
			
		||||
-3 = Noise (all non whitespace, non-base64 characters) 
 | 
			
		||||
-4 = Dangerous noise
 | 
			
		||||
-5 = Illegal noise (null byte)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const int8_t kBase64DecodeTable[128] = {
 | 
			
		||||
	/* 0x00 */ -5, 	/* 0x01 */ -3, 	/* 0x02 */ -3, 	/* 0x03 */ -3,
 | 
			
		||||
	/* 0x04 */ -3, 	/* 0x05 */ -3, 	/* 0x06 */ -3, 	/* 0x07 */ -3,
 | 
			
		||||
	/* 0x08 */ -3, 	/* 0x09 */ -2, 	/* 0x0a */ -2, 	/* 0x0b */ -2,
 | 
			
		||||
	/* 0x0c */ -2, 	/* 0x0d */ -2, 	/* 0x0e */ -3, 	/* 0x0f */ -3,
 | 
			
		||||
	/* 0x10 */ -3, 	/* 0x11 */ -3, 	/* 0x12 */ -3, 	/* 0x13 */ -3,
 | 
			
		||||
	/* 0x14 */ -3, 	/* 0x15 */ -3, 	/* 0x16 */ -3, 	/* 0x17 */ -3,
 | 
			
		||||
	/* 0x18 */ -3, 	/* 0x19 */ -3, 	/* 0x1a */ -3, 	/* 0x1b */ -3,
 | 
			
		||||
	/* 0x1c */ -3, 	/* 0x1d */ -3, 	/* 0x1e */ -3, 	/* 0x1f */ -3,
 | 
			
		||||
	/* ' ' */ -2,	/* '!' */ -3,	/* '"' */ -3,	/* '#' */ -3,
 | 
			
		||||
	/* '$' */ -3,	/* '%' */ -3,	/* '&' */ -3,	/* ''' */ -3,
 | 
			
		||||
	/* '(' */ -3,	/* ')' */ -3,	/* '*' */ -3,	/* '+' */ 62,
 | 
			
		||||
	/* ',' */ -3,	/* '-' */ -3,	/* '.' */ -3,	/* '/' */ 63,
 | 
			
		||||
	/* '0' */ 52,	/* '1' */ 53,	/* '2' */ 54,	/* '3' */ 55,
 | 
			
		||||
	/* '4' */ 56,	/* '5' */ 57,	/* '6' */ 58,	/* '7' */ 59,
 | 
			
		||||
	/* '8' */ 60,	/* '9' */ 61,	/* ':' */ -3,	/* ';' */ -3,
 | 
			
		||||
	/* '<' */ -3,	/* '=' */ -1,	/* '>' */ -3,	/* '?' */ -3,
 | 
			
		||||
	/* '@' */ -3,	/* 'A' */ 0,	/* 'B' */  1,	/* 'C' */  2,
 | 
			
		||||
	/* 'D' */  3,	/* 'E' */  4,	/* 'F' */  5,	/* 'G' */  6,
 | 
			
		||||
	/* 'H' */  7,	/* 'I' */  8,	/* 'J' */  9,	/* 'K' */ 10,
 | 
			
		||||
	/* 'L' */ 11,	/* 'M' */ 12,	/* 'N' */ 13,	/* 'O' */ 14,
 | 
			
		||||
	/* 'P' */ 15,	/* 'Q' */ 16,	/* 'R' */ 17,	/* 'S' */ 18,
 | 
			
		||||
	/* 'T' */ 19,	/* 'U' */ 20,	/* 'V' */ 21,	/* 'W' */ 22,
 | 
			
		||||
	/* 'X' */ 23,	/* 'Y' */ 24,	/* 'Z' */ 25,	/* '[' */ -3,
 | 
			
		||||
	/* '\' */ -3,	/* ']' */ -3,	/* '^' */ -3,	/* '_' */ -3,
 | 
			
		||||
	/* '`' */ -3,	/* 'a' */ 26,	/* 'b' */ 27,	/* 'c' */ 28,
 | 
			
		||||
	/* 'd' */ 29,	/* 'e' */ 30,	/* 'f' */ 31,	/* 'g' */ 32,
 | 
			
		||||
	/* 'h' */ 33,	/* 'i' */ 34,	/* 'j' */ 35,	/* 'k' */ 36,
 | 
			
		||||
	/* 'l' */ 37,	/* 'm' */ 38,	/* 'n' */ 39,	/* 'o' */ 40,
 | 
			
		||||
	/* 'p' */ 41,	/* 'q' */ 42,	/* 'r' */ 43,	/* 's' */ 44,
 | 
			
		||||
	/* 't' */ 45,	/* 'u' */ 46,	/* 'v' */ 47,	/* 'w' */ 48,
 | 
			
		||||
	/* 'x' */ 49,	/* 'y' */ 50,	/* 'z' */ 51,	/* '{' */ -3,
 | 
			
		||||
	/* '|' */ -3,	/* '}' */ -3,	/* '~' */ -3,	/* 0x7f */ -3
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const u_int8_t kBits_00000011 = 0x03;
 | 
			
		||||
const u_int8_t kBits_00001111 = 0x0F;
 | 
			
		||||
const u_int8_t kBits_00110000 = 0x30;
 | 
			
		||||
const u_int8_t kBits_00111100 = 0x3C;
 | 
			
		||||
const u_int8_t kBits_00111111 = 0x3F;
 | 
			
		||||
const u_int8_t kBits_11000000 = 0xC0;
 | 
			
		||||
const u_int8_t kBits_11110000 = 0xF0;
 | 
			
		||||
const u_int8_t kBits_11111100 = 0xFC;
 | 
			
		||||
 | 
			
		||||
size_t EstimateBas64EncodedDataSize(size_t inDataSize)
 | 
			
		||||
{
 | 
			
		||||
size_t theEncodedDataSize = (int)ceil(inDataSize / 3.0) * 4;
 | 
			
		||||
theEncodedDataSize = theEncodedDataSize / 72 * 74 + theEncodedDataSize % 72;
 | 
			
		||||
return(theEncodedDataSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t EstimateBas64DecodedDataSize(size_t inDataSize)
 | 
			
		||||
{
 | 
			
		||||
size_t theDecodedDataSize = (int)ceil(inDataSize / 4.0) * 3;
 | 
			
		||||
//theDecodedDataSize = theDecodedDataSize / 72 * 74 + theDecodedDataSize % 72;
 | 
			
		||||
return(theDecodedDataSize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize)
 | 
			
		||||
{
 | 
			
		||||
size_t theEncodedDataSize = EstimateBas64EncodedDataSize(inInputDataSize);
 | 
			
		||||
if (*ioOutputDataSize < theEncodedDataSize)
 | 
			
		||||
	return(false);
 | 
			
		||||
*ioOutputDataSize = theEncodedDataSize;
 | 
			
		||||
const u_int8_t *theInPtr = (const u_int8_t *)inInputData;
 | 
			
		||||
u_int32_t theInIndex = 0, theOutIndex = 0;
 | 
			
		||||
for (; theInIndex < (inInputDataSize / 3) * 3; theInIndex += 3)
 | 
			
		||||
	{
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (theInPtr[theInIndex + 2] & kBits_11000000) >> 6];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 2] & kBits_00111111) >> 0];
 | 
			
		||||
	if (theOutIndex % 74 == 72)
 | 
			
		||||
		{
 | 
			
		||||
		outOutputData[theOutIndex++] = '\r';
 | 
			
		||||
		outOutputData[theOutIndex++] = '\n';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
const size_t theRemainingBytes = inInputDataSize - theInIndex;
 | 
			
		||||
if (theRemainingBytes == 1)
 | 
			
		||||
	{
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (0 & kBits_11110000) >> 4];
 | 
			
		||||
	outOutputData[theOutIndex++] = '=';
 | 
			
		||||
	outOutputData[theOutIndex++] = '=';
 | 
			
		||||
	if (theOutIndex % 74 == 72)
 | 
			
		||||
		{
 | 
			
		||||
		outOutputData[theOutIndex++] = '\r';
 | 
			
		||||
		outOutputData[theOutIndex] = '\n';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
else if (theRemainingBytes == 2)
 | 
			
		||||
	{
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4];
 | 
			
		||||
	outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (0 & kBits_11000000) >> 6];
 | 
			
		||||
	outOutputData[theOutIndex++] = '=';
 | 
			
		||||
	if (theOutIndex % 74 == 72)
 | 
			
		||||
		{
 | 
			
		||||
		outOutputData[theOutIndex++] = '\r';
 | 
			
		||||
		outOutputData[theOutIndex] = '\n';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
return(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize)
 | 
			
		||||
{
 | 
			
		||||
memset(ioOutputData, '.', *ioOutputDataSize);
 | 
			
		||||
 | 
			
		||||
size_t theDecodedDataSize = EstimateBas64DecodedDataSize(inInputDataSize);
 | 
			
		||||
if (*ioOutputDataSize < theDecodedDataSize)
 | 
			
		||||
	return(false);
 | 
			
		||||
*ioOutputDataSize = 0;
 | 
			
		||||
const u_int8_t *theInPtr = (const u_int8_t *)inInputData;
 | 
			
		||||
u_int8_t *theOutPtr = (u_int8_t *)ioOutputData;
 | 
			
		||||
size_t theInIndex = 0, theOutIndex = 0;
 | 
			
		||||
u_int8_t theOutputOctet;
 | 
			
		||||
size_t theSequence = 0;
 | 
			
		||||
for (; theInIndex < inInputDataSize; )
 | 
			
		||||
	{
 | 
			
		||||
	int8_t theSextet = 0;
 | 
			
		||||
	
 | 
			
		||||
	int8_t theCurrentInputOctet = theInPtr[theInIndex];
 | 
			
		||||
	theSextet = kBase64DecodeTable[theCurrentInputOctet];
 | 
			
		||||
	if (theSextet == -1)
 | 
			
		||||
		break;
 | 
			
		||||
	while (theSextet == -2)
 | 
			
		||||
		{
 | 
			
		||||
		theCurrentInputOctet = theInPtr[++theInIndex];
 | 
			
		||||
		theSextet = kBase64DecodeTable[theCurrentInputOctet];
 | 
			
		||||
		}
 | 
			
		||||
	while (theSextet == -3)
 | 
			
		||||
		{
 | 
			
		||||
		theCurrentInputOctet = theInPtr[++theInIndex];
 | 
			
		||||
		theSextet = kBase64DecodeTable[theCurrentInputOctet];
 | 
			
		||||
		}
 | 
			
		||||
	if (theSequence == 0)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 2 & kBits_11111100;
 | 
			
		||||
		}
 | 
			
		||||
	else if (theSequence == 1)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet |= (theSextet >- 0 ? theSextet : 0) >> 4 & kBits_00000011;
 | 
			
		||||
		theOutPtr[theOutIndex++] = theOutputOctet;
 | 
			
		||||
		}
 | 
			
		||||
	else if (theSequence == 2)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 4 & kBits_11110000;
 | 
			
		||||
		}
 | 
			
		||||
	else if (theSequence == 3)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 2 & kBits_00001111;
 | 
			
		||||
		theOutPtr[theOutIndex++] = theOutputOctet;
 | 
			
		||||
		}
 | 
			
		||||
	else if (theSequence == 4)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 6 & kBits_11000000;
 | 
			
		||||
		}
 | 
			
		||||
	else if (theSequence == 5)
 | 
			
		||||
		{
 | 
			
		||||
		theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 0 & kBits_00111111;
 | 
			
		||||
		theOutPtr[theOutIndex++] = theOutputOctet;
 | 
			
		||||
		}
 | 
			
		||||
	theSequence = (theSequence + 1) % 6;
 | 
			
		||||
	if (theSequence != 2 && theSequence != 4)
 | 
			
		||||
		theInIndex++;
 | 
			
		||||
	}
 | 
			
		||||
*ioOutputDataSize = theOutIndex;
 | 
			
		||||
return(true);
 | 
			
		||||
}
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Base64Transcoder.h
 | 
			
		||||
 *  Base64Test
 | 
			
		||||
 *
 | 
			
		||||
 *  Created by Jonathan Wight on Tue Mar 18 2003.
 | 
			
		||||
 *  Copyright (c) 2003 Toxic Software. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 *  of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 *  in the Software without restriction, including without limitation the rights
 | 
			
		||||
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 *  copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 *  furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 *  The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 *  all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 *  THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
extern size_t EstimateBas64EncodedDataSize(size_t inDataSize);
 | 
			
		||||
extern size_t EstimateBas64DecodedDataSize(size_t inDataSize);
 | 
			
		||||
 | 
			
		||||
extern bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize);
 | 
			
		||||
extern bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize);
 | 
			
		||||
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPDebug.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 09.02.06.
 | 
			
		||||
//  Copyright 2009 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	#define MPLog(...) NSLog(__VA_ARGS__)
 | 
			
		||||
#else
 | 
			
		||||
	#define MPLog(...) do { } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuth.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.13.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#import <MPOAuth/MPOAuthAPI.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthAPIRequestLoader.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthAuthenticationMethod.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthAuthenticationMethodOAuth.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthCredentialStore.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthParameterFactory.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthConnection.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthURLRequest.h>
 | 
			
		||||
#import <MPOAuth/MPOAuthURLResponse.h>
 | 
			
		||||
@ -1,94 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAPI.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "MPOAuthCredentialStore.h"
 | 
			
		||||
#import "MPOAuthParameterFactory.h"
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenReceived;
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenRejected;
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenRefreshed;
 | 
			
		||||
extern NSString * const MPOAuthNotificationOAuthCredentialsReady;
 | 
			
		||||
extern NSString * const MPOAuthNotificationErrorHasOccurred;
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthCredentialRequestTokenKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialRequestTokenSecretKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialAccessTokenKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialAccessTokenSecretKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialSessionHandleKey;
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthTokenRefreshDateDefaultsKey;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	MPOAuthSignatureSchemePlainText,
 | 
			
		||||
	MPOAuthSignatureSchemeHMACSHA1,
 | 
			
		||||
	MPOAuthSignatureSchemeRSASHA1
 | 
			
		||||
} MPOAuthSignatureScheme;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	MPOAuthAuthenticationStateUnauthenticated		= 0,
 | 
			
		||||
	MPOAuthAuthenticationStateAuthenticating		= 1,
 | 
			
		||||
	MPOAuthAuthenticationStateAuthenticated			= 2
 | 
			
		||||
} MPOAuthAuthenticationState;
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthAPIInternalClient
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@class MPOAuthAuthenticationMethod;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAPI : NSObject <MPOAuthAPIInternalClient> {
 | 
			
		||||
@private
 | 
			
		||||
	id <MPOAuthCredentialStore, MPOAuthParameterFactory>		credentials;
 | 
			
		||||
	NSURL														*baseURL;
 | 
			
		||||
	NSURL														*authenticationURL;
 | 
			
		||||
	MPOAuthAuthenticationMethod									*authenticationMethod;
 | 
			
		||||
	MPOAuthSignatureScheme										signatureScheme;
 | 
			
		||||
	NSMutableArray												*activeLoaders;
 | 
			
		||||
	MPOAuthAuthenticationState									oauthAuthenticationState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredentials:(id)theCredentials;
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials;
 | 
			
		||||
- (void)setBaseURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)baseURL;
 | 
			
		||||
- (void)setAuthenticationURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)authenticationURL;
 | 
			
		||||
- (void)setAuthenticationMethod:(MPOAuthAuthenticationMethod *)theMethod;
 | 
			
		||||
- (MPOAuthAuthenticationMethod *)authenticationMethod;
 | 
			
		||||
- (void)setSignatureScheme:(MPOAuthSignatureScheme)theScheme;
 | 
			
		||||
- (MPOAuthSignatureScheme)signatureScheme;
 | 
			
		||||
 | 
			
		||||
- (void)setAuthenticationState:(MPOAuthAuthenticationState)theState;
 | 
			
		||||
- (MPOAuthAuthenticationState)authenticationState;
 | 
			
		||||
 | 
			
		||||
- (void)setActiveLoaders:(NSMutableArray *)theLoaders;
 | 
			
		||||
- (NSMutableArray *)activeLoaders;
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials andBaseURL:(NSURL *)inURL;
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials authenticationURL:(NSURL *)inAuthURL andBaseURL:(NSURL *)inBaseURL;
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials authenticationURL:(NSURL *)inAuthURL andBaseURL:(NSURL *)inBaseURL autoStart:(BOOL)aFlag;
 | 
			
		||||
 | 
			
		||||
- (void)authenticate;
 | 
			
		||||
- (BOOL)isAuthenticated;
 | 
			
		||||
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod withTarget:(id)inTarget andAction:(SEL)inAction;
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction;
 | 
			
		||||
- (void)performPOSTMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction;
 | 
			
		||||
- (void)performURLRequest:(NSURLRequest *)inRequest withTarget:(id)inTarget andAction:(SEL)inAction;
 | 
			
		||||
 | 
			
		||||
- (NSData *)dataForMethod:(NSString *)inMethod;
 | 
			
		||||
- (NSData *)dataForMethod:(NSString *)inMethod withParameters:(NSArray *)inParameters;
 | 
			
		||||
- (NSData *)dataForURL:(NSURL *)inURL andMethod:(NSString *)inMethod withParameters:(NSArray *)inParameters;
 | 
			
		||||
 | 
			
		||||
- (id)credentialNamed:(NSString *)inCredentialName;
 | 
			
		||||
- (void)setCredential:(id)inCredential withName:(NSString *)inName;
 | 
			
		||||
- (void)removeCredentialNamed:(NSString *)inName;
 | 
			
		||||
 | 
			
		||||
- (void)discardCredentials;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,253 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAPI.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthAPIRequestLoader.h"
 | 
			
		||||
#import "MPOAuthAPI.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "MPOAuthURLResponse.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "MPOAuthAuthenticationMethod.h"
 | 
			
		||||
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
 | 
			
		||||
NSString *kMPOAuthCredentialConsumerKey				= @"kMPOAuthCredentialConsumerKey";
 | 
			
		||||
NSString *kMPOAuthCredentialConsumerSecret			= @"kMPOAuthCredentialConsumerSecret";
 | 
			
		||||
NSString *kMPOAuthCredentialUsername				= @"kMPOAuthCredentialUsername";
 | 
			
		||||
NSString *kMPOAuthCredentialPassword				= @"kMPOAuthCredentialPassword";
 | 
			
		||||
NSString *kMPOAuthCredentialRequestToken			= @"kMPOAuthCredentialRequestToken";
 | 
			
		||||
NSString *kMPOAuthCredentialRequestTokenSecret		= @"kMPOAuthCredentialRequestTokenSecret";
 | 
			
		||||
NSString *kMPOAuthCredentialAccessToken				= @"kMPOAuthCredentialAccessToken";
 | 
			
		||||
NSString *kMPOAuthCredentialAccessTokenSecret		= @"kMPOAuthCredentialAccessTokenSecret";
 | 
			
		||||
NSString *kMPOAuthCredentialSessionHandle			= @"kMPOAuthCredentialSessionHandle";
 | 
			
		||||
 | 
			
		||||
NSString *kMPOAuthSignatureMethod					= @"kMPOAuthSignatureMethod";
 | 
			
		||||
NSString * const MPOAuthTokenRefreshDateDefaultsKey		= @"MPOAuthAutomaticTokenRefreshLastExpiryDate";
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAPI ()
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction usingHTTPMethod:(NSString *)inHTTPMethod;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthAPI
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials andBaseURL:(NSURL *)inBaseURL {
 | 
			
		||||
	return [self initWithCredentials:inCredentials authenticationURL:inBaseURL andBaseURL:inBaseURL];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials authenticationURL:(NSURL *)inAuthURL andBaseURL:(NSURL *)inBaseURL {
 | 
			
		||||
	return [self initWithCredentials:inCredentials authenticationURL:inBaseURL andBaseURL:inBaseURL autoStart:YES];	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials authenticationURL:(NSURL *)inAuthURL andBaseURL:(NSURL *)inBaseURL autoStart:(BOOL)aFlag {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		[self setAuthenticationURL:inAuthURL];
 | 
			
		||||
		[self setBaseURL:inBaseURL];
 | 
			
		||||
		[self setAuthenticationState:MPOAuthAuthenticationStateUnauthenticated];
 | 
			
		||||
		credentials = [[MPOAuthCredentialConcreteStore alloc] initWithCredentials:inCredentials forBaseURL:inBaseURL withAuthenticationURL:inAuthURL];
 | 
			
		||||
		[self setAuthenticationMethod:[[MPOAuthAuthenticationMethod alloc] initWithAPI:self forURL:inAuthURL]];
 | 
			
		||||
		[self setSignatureScheme:MPOAuthSignatureSchemeHMACSHA1];
 | 
			
		||||
 | 
			
		||||
		activeLoaders = [[NSMutableArray alloc] initWithCapacity:10];
 | 
			
		||||
		
 | 
			
		||||
		if (aFlag) {
 | 
			
		||||
			[self authenticate];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return self;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[credentials release];
 | 
			
		||||
	[baseURL release];
 | 
			
		||||
	[authenticationURL release];
 | 
			
		||||
	[authenticationMethod release];
 | 
			
		||||
	[activeLoaders release];
 | 
			
		||||
	
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredentials:(id)theCredentials {
 | 
			
		||||
	credentials = theCredentials;
 | 
			
		||||
}
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials {
 | 
			
		||||
	return credentials;
 | 
			
		||||
}
 | 
			
		||||
- (void)setBaseURL:(NSURL *)theURL {
 | 
			
		||||
	[baseURL release];
 | 
			
		||||
	baseURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)baseURL {
 | 
			
		||||
	return baseURL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setAuthenticationURL:(NSURL *)theURL {
 | 
			
		||||
	[authenticationURL release];
 | 
			
		||||
	authenticationURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)authenticationURL {
 | 
			
		||||
	return authenticationURL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setAuthenticationMethod:(MPOAuthAuthenticationMethod *)theMethod {
 | 
			
		||||
	[authenticationMethod release];
 | 
			
		||||
	authenticationMethod = [theMethod retain];
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthAuthenticationMethod *)authenticationMethod {
 | 
			
		||||
	return authenticationMethod;
 | 
			
		||||
}
 | 
			
		||||
- (void)setSignatureScheme:(MPOAuthSignatureScheme)theScheme {
 | 
			
		||||
	signatureScheme = theScheme;
 | 
			
		||||
	
 | 
			
		||||
	NSString *methodString = @"HMAC-SHA1";
 | 
			
		||||
	
 | 
			
		||||
	switch (signatureScheme) {
 | 
			
		||||
		case MPOAuthSignatureSchemePlainText:
 | 
			
		||||
			methodString = @"PLAINTEXT";
 | 
			
		||||
			break;
 | 
			
		||||
		case MPOAuthSignatureSchemeRSASHA1:
 | 
			
		||||
			methodString = @"RSA-SHA1";
 | 
			
		||||
		case MPOAuthSignatureSchemeHMACSHA1:
 | 
			
		||||
		default:
 | 
			
		||||
			// already initted to the default
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[(MPOAuthCredentialConcreteStore *)credentials setSignatureMethod:methodString];
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthSignatureScheme)signatureScheme {
 | 
			
		||||
	return signatureScheme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAuthenticationState:(MPOAuthAuthenticationState)theState {
 | 
			
		||||
	oauthAuthenticationState = theState;
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthAuthenticationState)authenticationState {
 | 
			
		||||
	return oauthAuthenticationState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setActiveLoaders:(NSMutableArray *)theLoaders {
 | 
			
		||||
	[activeLoaders release];
 | 
			
		||||
	activeLoaders = [theLoaders retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSMutableArray *)activeLoaders {
 | 
			
		||||
	return activeLoaders;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)authenticate {
 | 
			
		||||
	NSAssert([credentials consumerKey], @"A Consumer Key is required for use of OAuth.");
 | 
			
		||||
	[authenticationMethod authenticate];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isAuthenticated {
 | 
			
		||||
	return ([self authenticationState] == MPOAuthAuthenticationStateAuthenticated);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod withTarget:(id)inTarget andAction:(SEL)inAction {
 | 
			
		||||
	[self performMethod:inMethod atURL:baseURL withParameters:nil withTarget:inTarget andAction:inAction usingHTTPMethod:@"GET"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction {
 | 
			
		||||
	[self performMethod:inMethod atURL:inURL withParameters:inParameters withTarget:inTarget andAction:inAction usingHTTPMethod:@"GET"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)performPOSTMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction {
 | 
			
		||||
	[self performMethod:inMethod atURL:inURL withParameters:inParameters withTarget:inTarget andAction:inAction usingHTTPMethod:@"POST"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)performMethod:(NSString *)inMethod atURL:(NSURL *)inURL withParameters:(NSArray *)inParameters withTarget:(id)inTarget andAction:(SEL)inAction usingHTTPMethod:(NSString *)inHTTPMethod {
 | 
			
		||||
	if (!inMethod && ![inURL path] && ![inURL query]) {
 | 
			
		||||
		[NSException raise:@"MPOAuthNilMethodRequestException" format:@"Nil was passed as the method to be performed on %@", inURL];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	NSURL *requestURL = inMethod ? [NSURL URLWithString:inMethod relativeToURL:inURL] : inURL;
 | 
			
		||||
	MPOAuthURLRequest *aRequest = [[MPOAuthURLRequest alloc] initWithURL:requestURL andParameters:inParameters];
 | 
			
		||||
	MPOAuthAPIRequestLoader *loader = [[MPOAuthAPIRequestLoader alloc] initWithRequest:aRequest];
 | 
			
		||||
	
 | 
			
		||||
	aRequest.HTTPMethod = inHTTPMethod;
 | 
			
		||||
	loader.credentials = credentials;
 | 
			
		||||
	loader.target = inTarget;
 | 
			
		||||
	loader.action = inAction ? inAction : @selector(_performedLoad:receivingData:);
 | 
			
		||||
	
 | 
			
		||||
	[loader loadSynchronously:NO];
 | 
			
		||||
	//	[activeLoaders addObject:loader];
 | 
			
		||||
	
 | 
			
		||||
	[loader release];
 | 
			
		||||
	[aRequest release];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)performURLRequest:(NSURLRequest *)inRequest withTarget:(id)inTarget andAction:(SEL)inAction {
 | 
			
		||||
	if (!inRequest && ![[inRequest URL] path] && ![[inRequest URL] query]) {
 | 
			
		||||
		[NSException raise:@"MPOAuthNilMethodRequestException" format:@"Nil was passed as the method to be performed on %@", inRequest];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MPOAuthURLRequest *aRequest = [[MPOAuthURLRequest alloc] initWithURLRequest:inRequest];
 | 
			
		||||
	MPOAuthAPIRequestLoader *loader = [[MPOAuthAPIRequestLoader alloc] initWithRequest:aRequest];
 | 
			
		||||
	
 | 
			
		||||
	loader.credentials = credentials;
 | 
			
		||||
	loader.target = inTarget;
 | 
			
		||||
	loader.action = inAction ? inAction : @selector(_performedLoad:receivingData:);
 | 
			
		||||
	
 | 
			
		||||
	[loader loadSynchronously:NO];
 | 
			
		||||
	//	[activeLoaders addObject:loader];
 | 
			
		||||
	
 | 
			
		||||
	[loader release];
 | 
			
		||||
	[aRequest release];	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSData *)dataForMethod:(NSString *)inMethod {
 | 
			
		||||
	return [self dataForURL:baseURL andMethod:inMethod withParameters:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSData *)dataForMethod:(NSString *)inMethod withParameters:(NSArray *)inParameters {
 | 
			
		||||
	return [self dataForURL:baseURL andMethod:inMethod withParameters:inParameters];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSData *)dataForURL:(NSURL *)inURL andMethod:(NSString *)inMethod withParameters:(NSArray *)inParameters {
 | 
			
		||||
	NSURL *requestURL = [NSURL URLWithString:inMethod relativeToURL:inURL];
 | 
			
		||||
	MPOAuthURLRequest *aRequest = [[MPOAuthURLRequest alloc] initWithURL:requestURL andParameters:inParameters];
 | 
			
		||||
	MPOAuthAPIRequestLoader *loader = [[MPOAuthAPIRequestLoader alloc] initWithRequest:aRequest];
 | 
			
		||||
 | 
			
		||||
	loader.credentials = credentials;
 | 
			
		||||
	[loader loadSynchronously:YES];
 | 
			
		||||
	
 | 
			
		||||
	[loader autorelease];
 | 
			
		||||
	[aRequest release];
 | 
			
		||||
	
 | 
			
		||||
	return loader.data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (id)credentialNamed:(NSString *)inCredentialName {
 | 
			
		||||
	return [credentials credentialNamed:inCredentialName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredential:(id)inCredential withName:(NSString *)inName {
 | 
			
		||||
	[(MPOAuthCredentialConcreteStore *)credentials setCredential:inCredential withName:inName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeCredentialNamed:(NSString *)inName {
 | 
			
		||||
	[(MPOAuthCredentialConcreteStore *)credentials removeCredentialNamed:inName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)discardCredentials {
 | 
			
		||||
	[credentials discardOAuthCredentials];
 | 
			
		||||
	
 | 
			
		||||
	[self setAuthenticationState:MPOAuthAuthenticationStateUnauthenticated];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
#pragma mark - Private APIs -
 | 
			
		||||
 | 
			
		||||
- (void)_performedLoad:(MPOAuthAPIRequestLoader *)inLoader receivingData:(NSData *)inData {
 | 
			
		||||
//	NSLog(@"loaded %@, and got %@", inLoader, inData);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,53 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAPIRequestLoader.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthNotificationRequestTokenReceived;
 | 
			
		||||
extern NSString * const MPOAuthNotificationRequestTokenRejected;
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenReceived;
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenRejected;
 | 
			
		||||
extern NSString * const MPOAuthNotificationAccessTokenRefreshed;
 | 
			
		||||
extern NSString * const MPOAuthNotificationErrorHasOccurred;
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthCredentialStore;
 | 
			
		||||
@protocol MPOAuthParameterFactory;
 | 
			
		||||
 | 
			
		||||
@class MPOAuthURLRequest;
 | 
			
		||||
@class MPOAuthURLResponse;
 | 
			
		||||
@class MPOAuthCredentialConcreteStore;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAPIRequestLoader : NSObject {
 | 
			
		||||
	MPOAuthCredentialConcreteStore	*credentials;
 | 
			
		||||
	MPOAuthURLRequest				*oauthRequest;
 | 
			
		||||
	MPOAuthURLResponse				*oauthResponse;
 | 
			
		||||
	NSMutableData					*data;
 | 
			
		||||
	NSString						*responseString;
 | 
			
		||||
	NSError							*error;
 | 
			
		||||
	id								target;
 | 
			
		||||
	SEL								action;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredentials:(id)theCredentials;
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials;
 | 
			
		||||
- (void)setOauthRequest:(MPOAuthURLRequest *)theRequest;
 | 
			
		||||
- (MPOAuthURLRequest *)oauthRequest;
 | 
			
		||||
- (void)setOauthResponse:(MPOAuthURLResponse *)theResponse;
 | 
			
		||||
- (MPOAuthURLResponse *)oauthResponse;
 | 
			
		||||
- (NSData *)data;
 | 
			
		||||
- (NSString *)responseString;
 | 
			
		||||
- (void)setTarget:(id)theTarget;
 | 
			
		||||
- (id)target;
 | 
			
		||||
- (void)setAction:(SEL)theAction;
 | 
			
		||||
- (SEL)action;
 | 
			
		||||
 | 
			
		||||
- (id)initWithURL:(NSURL *)inURL;
 | 
			
		||||
- (id)initWithRequest:(MPOAuthURLRequest *)inRequest;
 | 
			
		||||
 | 
			
		||||
- (void)loadSynchronously:(BOOL)inSynchronous;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,231 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAPIRequestLoader.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthAPIRequestLoader.h"
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "MPOAuthURLResponse.h"
 | 
			
		||||
#import "MPOAuthConnection.h"
 | 
			
		||||
#import "MPOAuthCredentialStore.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "NSURLResponse+Encoding.h"
 | 
			
		||||
#import "MPDebug.h"
 | 
			
		||||
 | 
			
		||||
NSString * const MPOAuthNotificationRequestTokenReceived	= @"MPOAuthNotificationRequestTokenReceived";
 | 
			
		||||
NSString * const MPOAuthNotificationRequestTokenRejected	= @"MPOAuthNotificationRequestTokenRejected";
 | 
			
		||||
NSString * const MPOAuthNotificationAccessTokenReceived		= @"MPOAuthNotificationAccessTokenReceived";
 | 
			
		||||
NSString * const MPOAuthNotificationAccessTokenRejected		= @"MPOAuthNotificationAccessTokenRejected";
 | 
			
		||||
NSString * const MPOAuthNotificationAccessTokenRefreshed	= @"MPOAuthNotificationAccessTokenRefreshed";
 | 
			
		||||
NSString * const MPOAuthNotificationOAuthCredentialsReady	= @"MPOAuthNotificationOAuthCredentialsReady";
 | 
			
		||||
NSString * const MPOAuthNotificationErrorHasOccurred		= @"MPOAuthNotificationErrorHasOccurred";
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAPIRequestLoader ()
 | 
			
		||||
- (void)_interrogateResponseForOAuthData;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthAPIInternalClient;
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthAPIRequestLoader
 | 
			
		||||
 | 
			
		||||
- (id)initWithURL:(NSURL *)inURL {
 | 
			
		||||
	return [self initWithRequest:[[[MPOAuthURLRequest alloc] initWithURL:inURL andParameters:nil] autorelease]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithRequest:(MPOAuthURLRequest *)inRequest {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		[self setOauthRequest:inRequest];
 | 
			
		||||
		data = [[NSMutableData alloc] init];
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[credentials release];
 | 
			
		||||
	[oauthRequest release];
 | 
			
		||||
	[oauthResponse release];
 | 
			
		||||
	[data release];
 | 
			
		||||
	[responseString release];
 | 
			
		||||
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredentials:(id)theCredentials {
 | 
			
		||||
	[credentials release];
 | 
			
		||||
	credentials = [theCredentials retain];
 | 
			
		||||
}
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials {
 | 
			
		||||
	return credentials;
 | 
			
		||||
}
 | 
			
		||||
- (void)setOauthRequest:(MPOAuthURLRequest *)theRequest {
 | 
			
		||||
	[oauthRequest release];
 | 
			
		||||
	oauthRequest = [theRequest retain];
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthURLRequest *)oauthRequest {
 | 
			
		||||
	return oauthRequest;
 | 
			
		||||
}
 | 
			
		||||
- (void)setOauthResponse:(MPOAuthURLResponse *)theResponse {
 | 
			
		||||
	[oauthResponse release];
 | 
			
		||||
	oauthResponse = [theResponse retain];
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthURLResponse *)oauthResponse {
 | 
			
		||||
	if (oauthResponse==nil)
 | 
			
		||||
		oauthResponse = [[MPOAuthURLResponse alloc] init];
 | 
			
		||||
	return oauthResponse;
 | 
			
		||||
}
 | 
			
		||||
- (NSData *)data {
 | 
			
		||||
	return data;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)responseString {
 | 
			
		||||
	if (responseString==nil)
 | 
			
		||||
		responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 | 
			
		||||
	return responseString;
 | 
			
		||||
}
 | 
			
		||||
- (void)setTarget:(id)theTarget {
 | 
			
		||||
	target = theTarget;
 | 
			
		||||
}
 | 
			
		||||
- (id)target {
 | 
			
		||||
	return target;
 | 
			
		||||
}
 | 
			
		||||
- (void)setAction:(SEL)theAction {
 | 
			
		||||
	action = theAction;
 | 
			
		||||
}
 | 
			
		||||
- (SEL)action {
 | 
			
		||||
	return action;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)loadSynchronously:(BOOL)inSynchronous {
 | 
			
		||||
	NSAssert(credentials, @"Unable to load without valid credentials");
 | 
			
		||||
	NSAssert(credentials.consumerKey, @"Unable to load, credentials contain no consumer key");
 | 
			
		||||
	
 | 
			
		||||
	if (!inSynchronous) {
 | 
			
		||||
		[MPOAuthConnection connectionWithRequest:oauthRequest delegate:self credentials:credentials];
 | 
			
		||||
	} else {
 | 
			
		||||
		MPOAuthURLResponse *theOAuthResponse = nil;
 | 
			
		||||
		data = [[MPOAuthConnection sendSynchronousRequest:oauthRequest usingCredentials:credentials returningResponse:&theOAuthResponse error:nil] retain];
 | 
			
		||||
		[self setOauthResponse:theOAuthResponse];
 | 
			
		||||
		[self _interrogateResponseForOAuthData];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)theError {
 | 
			
		||||
		MPLog(@"%p: [%@ %@] %@, %@", self, NSStringFromClass([self class]), NSStringFromSelector(_cmd), connection, theError);
 | 
			
		||||
	if ([target respondsToSelector:@selector(loader:didFailWithError:)]) {
 | 
			
		||||
		[target performSelector: @selector(loader:didFailWithError:) withObject: self withObject: theError];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 | 
			
		||||
	[[self oauthResponse] setResponse:response];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
 | 
			
		||||
	MPLog(@"%@", NSStringFromSelector(_cmd));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData {
 | 
			
		||||
	[data appendData:theData];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse {
 | 
			
		||||
	MPLog( @"[%@ %@]: %@, %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), request, redirectResponse);
 | 
			
		||||
	return request;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
 | 
			
		||||
	[self _interrogateResponseForOAuthData];
 | 
			
		||||
	
 | 
			
		||||
	if (action) {
 | 
			
		||||
		if ([target conformsToProtocol:@protocol(MPOAuthAPIInternalClient)]) {
 | 
			
		||||
			[target performSelector:action withObject:self withObject:data];
 | 
			
		||||
		} else {
 | 
			
		||||
			[target performSelector:action withObject:[oauthRequest url] withObject:responseString];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)_interrogateResponseForOAuthData {
 | 
			
		||||
	NSString *response = responseString;
 | 
			
		||||
	NSDictionary *foundParameters = nil;
 | 
			
		||||
	int status = [(NSHTTPURLResponse *)[[self oauthResponse] response] statusCode];
 | 
			
		||||
	
 | 
			
		||||
	if ([response length] > 5 && [[response substringToIndex:5] isEqualToString:@"oauth"]) {
 | 
			
		||||
		foundParameters = [MPURLRequestParameter parameterDictionaryFromString:response];
 | 
			
		||||
		oauthResponse.oauthParameters = foundParameters;
 | 
			
		||||
		
 | 
			
		||||
		if (status == 401 || ([response length] > 13 && [[response substringToIndex:13] isEqualToString:@"oauth_problem"])) {
 | 
			
		||||
			NSString *aParameterValue = nil;
 | 
			
		||||
			MPLog(@"oauthProblem = %@", foundParameters);
 | 
			
		||||
			
 | 
			
		||||
			if ([foundParameters count] && (aParameterValue = [foundParameters objectForKey:@"oauth_problem"])) {
 | 
			
		||||
				if ([aParameterValue isEqualToString:@"token_rejected"]) {
 | 
			
		||||
					if ([credentials requestToken] && ![credentials accessToken]) {
 | 
			
		||||
						[credentials setRequestToken:nil];
 | 
			
		||||
						[credentials setRequestTokenSecret:nil];
 | 
			
		||||
						
 | 
			
		||||
						[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationRequestTokenRejected
 | 
			
		||||
																			object:nil
 | 
			
		||||
																		  userInfo:foundParameters];
 | 
			
		||||
					} else if ([credentials accessToken] && ![credentials requestToken]) {
 | 
			
		||||
						// your access token may be invalid due to a number of reasons so it's up to the
 | 
			
		||||
						// user to decide whether or not to remove them
 | 
			
		||||
						[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenRejected
 | 
			
		||||
																			object:nil
 | 
			
		||||
																		  userInfo:foundParameters];
 | 
			
		||||
						
 | 
			
		||||
					}						
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				// something's messed up, so throw an error
 | 
			
		||||
				[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationErrorHasOccurred
 | 
			
		||||
																	object:nil
 | 
			
		||||
																  userInfo:foundParameters];
 | 
			
		||||
			}
 | 
			
		||||
		} else if ([response length] > 11 && [[response substringToIndex:11] isEqualToString:@"oauth_token"]) {
 | 
			
		||||
			NSString *aParameterValue = nil;
 | 
			
		||||
			MPLog(@"foundParameters = %@", foundParameters);
 | 
			
		||||
 | 
			
		||||
			if ([foundParameters count] && (aParameterValue = [foundParameters objectForKey:@"oauth_token"])) {
 | 
			
		||||
				if (![credentials requestToken] && ![credentials accessToken]) {
 | 
			
		||||
					[credentials setRequestToken:aParameterValue];
 | 
			
		||||
					[credentials setRequestTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
 | 
			
		||||
					
 | 
			
		||||
					[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationRequestTokenReceived
 | 
			
		||||
																		object:nil
 | 
			
		||||
																	  userInfo:foundParameters];
 | 
			
		||||
					
 | 
			
		||||
				} else if (![credentials accessToken] && [credentials requestToken]) {
 | 
			
		||||
					[credentials setRequestToken:nil];
 | 
			
		||||
					[credentials setRequestTokenSecret:nil];
 | 
			
		||||
					[credentials setAccessToken:aParameterValue];
 | 
			
		||||
					[credentials setAccessTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
 | 
			
		||||
					
 | 
			
		||||
					[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenReceived
 | 
			
		||||
																		object:nil
 | 
			
		||||
																	  userInfo:foundParameters];
 | 
			
		||||
					
 | 
			
		||||
				} else if ([credentials accessToken] && ![credentials requestToken]) {
 | 
			
		||||
					// replace the current token
 | 
			
		||||
					[credentials setAccessToken:aParameterValue];
 | 
			
		||||
					[credentials setAccessTokenSecret:[foundParameters objectForKey:@"oauth_token_secret"]];
 | 
			
		||||
					
 | 
			
		||||
					[[NSNotificationCenter defaultCenter] postNotificationName:MPOAuthNotificationAccessTokenRefreshed
 | 
			
		||||
																		object:nil
 | 
			
		||||
																	  userInfo:foundParameters];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAuthenticationMethod.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 09.12.19.
 | 
			
		||||
//  Copyright 2009 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthAccessTokenURLKey;
 | 
			
		||||
 | 
			
		||||
@class MPOAuthAPI;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAuthenticationMethod : NSObject {
 | 
			
		||||
	MPOAuthAPI								*oauthAPI;
 | 
			
		||||
	NSURL									*oauthGetAccessTokenURL;
 | 
			
		||||
	NSTimer									*refreshTimer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setOauthAPI:(MPOAuthAPI *)theAPI;
 | 
			
		||||
- (MPOAuthAPI *)oauthAPI;
 | 
			
		||||
- (void)setOauthGetAccessTokenURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)oauthGetAccessTokenURL;
 | 
			
		||||
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL;
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL withConfiguration:(NSDictionary *)inConfig;
 | 
			
		||||
- (void)authenticate;
 | 
			
		||||
 | 
			
		||||
- (void)setTokenRefreshInterval:(NSTimeInterval)inTimeInterval;
 | 
			
		||||
- (void)refreshAccessToken;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,140 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAuthenticationMethod.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 09.12.19.
 | 
			
		||||
//  Copyright 2009 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthAuthenticationMethod.h"
 | 
			
		||||
#import "MPOAuthAuthenticationMethodOAuth.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
 | 
			
		||||
NSString * const MPOAuthAccessTokenURLKey					= @"MPOAuthAccessTokenURL";
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAuthenticationMethod ()
 | 
			
		||||
+ (Class)_authorizationMethodClassForURL:(NSURL *)inBaseURL withConfiguration:(NSDictionary **)outConfig;
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL withConfiguration:(NSDictionary *)inConfig;
 | 
			
		||||
- (void)_automaticallyRefreshAccessToken:(NSTimer *)inTimer;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthAuthenticationMethod
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL {
 | 
			
		||||
	return [self initWithAPI:inAPI forURL:inURL withConfiguration:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL withConfiguration:(NSDictionary *)inConfig {
 | 
			
		||||
	if ([[self class] isEqual:[MPOAuthAuthenticationMethod class]]) {
 | 
			
		||||
		NSDictionary *configuration = nil;
 | 
			
		||||
		Class methodClass = [[self class] _authorizationMethodClassForURL:inURL withConfiguration:&configuration];
 | 
			
		||||
		[self release];
 | 
			
		||||
		
 | 
			
		||||
		self = [[methodClass alloc] initWithAPI:inAPI forURL:inURL withConfiguration:configuration];
 | 
			
		||||
	} else if ((self = [super init])) {
 | 
			
		||||
		oauthAPI = inAPI;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[oauthGetAccessTokenURL release];
 | 
			
		||||
 | 
			
		||||
	[refreshTimer invalidate];
 | 
			
		||||
	[refreshTimer release];
 | 
			
		||||
	refreshTimer = nil;
 | 
			
		||||
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setOauthAPI:(MPOAuthAPI *)theAPI {
 | 
			
		||||
	oauthAPI = theAPI;
 | 
			
		||||
}
 | 
			
		||||
- (MPOAuthAPI *)oauthAPI {
 | 
			
		||||
	return oauthAPI;
 | 
			
		||||
}
 | 
			
		||||
- (void)setOauthGetAccessTokenURL:(NSURL *)theURL {
 | 
			
		||||
	[oauthGetAccessTokenURL release];
 | 
			
		||||
	oauthGetAccessTokenURL =  [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)oauthGetAccessTokenURL {
 | 
			
		||||
	return oauthGetAccessTokenURL;
 | 
			
		||||
}
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
+ (Class)_authorizationMethodClassForURL:(NSURL *)inBaseURL withConfiguration:(NSDictionary **)outConfig {
 | 
			
		||||
	Class methodClass = [MPOAuthAuthenticationMethodOAuth class];
 | 
			
		||||
	NSString *oauthConfigPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"oauthAutoConfig" ofType:@"plist"];
 | 
			
		||||
	NSDictionary *oauthConfigDictionary = [NSDictionary dictionaryWithContentsOfFile:oauthConfigPath];
 | 
			
		||||
	NSEnumerator *enumerator = [oauthConfigDictionary keyEnumerator];
 | 
			
		||||
	NSString *domainString = nil;
 | 
			
		||||
	while ((domainString = [enumerator nextObject])) {
 | 
			
		||||
		if ([inBaseURL domainMatches:domainString]) {
 | 
			
		||||
			NSDictionary *oauthConfig = [oauthConfigDictionary objectForKey:domainString];
 | 
			
		||||
			
 | 
			
		||||
			NSArray *requestedMethods = [oauthConfig objectForKey:@"MPOAuthAuthenticationPreferredMethods"];
 | 
			
		||||
			NSString *requestedMethod = nil;
 | 
			
		||||
			for (int i=0; i<[requestedMethods count]; i++) {
 | 
			
		||||
				requestedMethod = [requestedMethods objectAtIndex:i];
 | 
			
		||||
				Class requestedMethodClass = NSClassFromString(requestedMethod);
 | 
			
		||||
				
 | 
			
		||||
				if (requestedMethodClass) {
 | 
			
		||||
					methodClass = requestedMethodClass;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (requestedMethod) {
 | 
			
		||||
				*outConfig = [oauthConfig objectForKey:requestedMethod];
 | 
			
		||||
			} else {
 | 
			
		||||
				*outConfig = oauthConfig;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return methodClass; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)authenticate {
 | 
			
		||||
	[NSException raise:@"Not Implemented" format:@"All subclasses of MPOAuthAuthenticationMethod are required to implement -authenticate"];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setTokenRefreshInterval:(NSTimeInterval)inTimeInterval {
 | 
			
		||||
	if (refreshTimer==nil && inTimeInterval > 0.0) {
 | 
			
		||||
		refreshTimer = [[NSTimer scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(_automaticallyRefreshAccessToken:) userInfo:nil repeats:YES] retain];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)refreshAccessToken {
 | 
			
		||||
	MPURLRequestParameter *sessionHandleParameter = nil;
 | 
			
		||||
	MPOAuthCredentialConcreteStore *credentials = (MPOAuthCredentialConcreteStore *)[oauthAPI credentials];
 | 
			
		||||
	
 | 
			
		||||
	if (credentials.sessionHandle) {
 | 
			
		||||
		sessionHandleParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
		sessionHandleParameter.name = @"oauth_session_handle";
 | 
			
		||||
		sessionHandleParameter.value = credentials.sessionHandle;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[oauthAPI performMethod:nil
 | 
			
		||||
						   atURL:oauthGetAccessTokenURL
 | 
			
		||||
				  withParameters:sessionHandleParameter ? [NSArray arrayWithObject:sessionHandleParameter] : nil
 | 
			
		||||
					  withTarget:nil
 | 
			
		||||
					   andAction:nil];
 | 
			
		||||
	
 | 
			
		||||
	[sessionHandleParameter release];	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)_automaticallyRefreshAccessToken:(NSTimer *)inTimer {
 | 
			
		||||
	[self refreshAccessToken];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,50 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAuthenticationMethodOAuth.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 09.12.19.
 | 
			
		||||
//  Copyright 2009 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "MPOAuthAuthenticationMethod.h"
 | 
			
		||||
#import "MPOAuthAPI.h"
 | 
			
		||||
#import "MPOAuthAPIRequestLoader.h"
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthNotificationRequestTokenReceived;
 | 
			
		||||
extern NSString * const MPOAuthNotificationRequestTokenRejected;
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthAuthenticationMethodOAuthDelegate;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAuthenticationMethodOAuth : MPOAuthAuthenticationMethod <MPOAuthAPIInternalClient> {
 | 
			
		||||
	NSURL									*oauthRequestTokenURL;
 | 
			
		||||
	NSURL									*oauthAuthorizeTokenURL;
 | 
			
		||||
	BOOL									oauth10aModeActive;
 | 
			
		||||
	
 | 
			
		||||
	id<MPOAuthAuthenticationMethodOAuthDelegate> delegate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setDelegate:(id)theDelegate;
 | 
			
		||||
- (id<MPOAuthAuthenticationMethodOAuthDelegate>)delegate;
 | 
			
		||||
 | 
			
		||||
- (void)setOauthRequestTokenURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)oauthRequestTokenURL;
 | 
			
		||||
- (void)setOauthAuthorizeTokenURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)oauthAuthorizeTokenURL;
 | 
			
		||||
 | 
			
		||||
- (void)setOauth10aModeActive:(BOOL)isActive;
 | 
			
		||||
- (BOOL)oauth10aModeActive;
 | 
			
		||||
 | 
			
		||||
- (void)authenticate;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthAuthenticationMethodOAuthDelegate <NSObject>
 | 
			
		||||
- (NSURL *)callbackURLForCompletedUserAuthorization;
 | 
			
		||||
- (BOOL)automaticallyRequestAuthenticationFromURL:(NSURL *)inAuthURL withCallbackURL:(NSURL *)inCallbackURL;
 | 
			
		||||
 | 
			
		||||
@optional
 | 
			
		||||
- (NSString *)oauthVerifierForCompletedUserAuthorization;
 | 
			
		||||
- (void)authenticationDidFailWithError:(NSError *)error;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@ -1,231 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthAuthenticationMethodOAuth.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 09.12.19.
 | 
			
		||||
//  Copyright 2009 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthAuthenticationMethodOAuth.h"
 | 
			
		||||
#import "MPOAuthAPI.h"
 | 
			
		||||
#import "MPOAuthAPIRequestLoader.h"
 | 
			
		||||
#import "MPOAuthURLResponse.h"
 | 
			
		||||
#import "MPOAuthCredentialStore.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPDebug.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
 | 
			
		||||
NSString *MPOAuthRequestTokenURLKey					= @"MPOAuthRequestTokenURL";
 | 
			
		||||
NSString *MPOAuthUserAuthorizationURLKey			= @"MPOAuthUserAuthorizationURL";
 | 
			
		||||
NSString *MPOAuthUserAuthorizationMobileURLKey		= @"MPOAuthUserAuthorizationMobileURL";
 | 
			
		||||
 | 
			
		||||
NSString * const MPOAuthCredentialRequestTokenKey			= @"oauth_token_request";
 | 
			
		||||
NSString * const MPOAuthCredentialRequestTokenSecretKey		= @"oauth_token_request_secret";
 | 
			
		||||
NSString * const MPOAuthCredentialAccessTokenKey			= @"oauth_token_access";
 | 
			
		||||
NSString * const MPOAuthCredentialAccessTokenSecretKey		= @"oauth_token_access_secret";
 | 
			
		||||
NSString * const MPOAuthCredentialSessionHandleKey			= @"oauth_session_handle";
 | 
			
		||||
NSString * const MPOAuthCredentialVerifierKey				= @"oauth_verifier";
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthAuthenticationMethodOAuth ()
 | 
			
		||||
- (void)_authenticationRequestForRequestToken;
 | 
			
		||||
- (void)_authenticationRequestForUserPermissionsConfirmationAtURL:(NSURL *)inURL;
 | 
			
		||||
- (void)_authenticationRequestForAccessToken;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthAuthenticationMethodOAuth
 | 
			
		||||
 | 
			
		||||
- (id)initWithAPI:(MPOAuthAPI *)inAPI forURL:(NSURL *)inURL withConfiguration:(NSDictionary *)inConfig {
 | 
			
		||||
	if ((self = [super initWithAPI:inAPI forURL:inURL withConfiguration:inConfig])) {
 | 
			
		||||
		
 | 
			
		||||
		NSAssert( [inConfig count] >= 3, @"Incorrect number of oauth authorization methods");
 | 
			
		||||
		[self setOauthRequestTokenURL:[NSURL URLWithString:[inConfig objectForKey:MPOAuthRequestTokenURLKey]]];
 | 
			
		||||
		[self setOauthAuthorizeTokenURL:[NSURL URLWithString:[inConfig objectForKey:MPOAuthUserAuthorizationURLKey]]];
 | 
			
		||||
		[self setOauthGetAccessTokenURL:[NSURL URLWithString:[inConfig objectForKey:MPOAuthAccessTokenURLKey]]];
 | 
			
		||||
		
 | 
			
		||||
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_requestTokenReceived:) name:MPOAuthNotificationRequestTokenReceived object:nil];
 | 
			
		||||
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_requestTokenRejected:) name:MPOAuthNotificationRequestTokenRejected object:nil];
 | 
			
		||||
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessTokenReceived:) name:MPOAuthNotificationAccessTokenReceived object:nil];		
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[oauthRequestTokenURL release];
 | 
			
		||||
	[oauthAuthorizeTokenURL release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setDelegate:(id)theDelegate {
 | 
			
		||||
	delegate = theDelegate;
 | 
			
		||||
}
 | 
			
		||||
- (id<MPOAuthAuthenticationMethodOAuthDelegate>)delegate {
 | 
			
		||||
	return delegate;
 | 
			
		||||
}
 | 
			
		||||
- (void)setOauthRequestTokenURL:(NSURL *)theURL {
 | 
			
		||||
	[oauthRequestTokenURL release];
 | 
			
		||||
	oauthRequestTokenURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)oauthRequestTokenURL {
 | 
			
		||||
	return oauthRequestTokenURL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setOauthAuthorizeTokenURL:(NSURL *)theURL {
 | 
			
		||||
	[oauthAuthorizeTokenURL release];
 | 
			
		||||
	oauthAuthorizeTokenURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)oauthAuthorizeTokenURL {
 | 
			
		||||
	return oauthAuthorizeTokenURL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setOauth10aModeActive:(BOOL)isActive {
 | 
			
		||||
	oauth10aModeActive = isActive;
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)oauth10aModeActive {
 | 
			
		||||
	return oauth10aModeActive;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)authenticate {
 | 
			
		||||
	id <MPOAuthCredentialStore> credentials = [[self oauthAPI] credentials];
 | 
			
		||||
	
 | 
			
		||||
	if (![credentials accessToken] && ![credentials requestToken]) {
 | 
			
		||||
		[self _authenticationRequestForRequestToken];
 | 
			
		||||
	} else if (![credentials accessToken]) {
 | 
			
		||||
		[self _authenticationRequestForAccessToken];
 | 
			
		||||
	} else if ([credentials accessToken] && [[NSUserDefaults standardUserDefaults] objectForKey:MPOAuthTokenRefreshDateDefaultsKey]) {
 | 
			
		||||
		NSTimeInterval expiryDateInterval = [[NSUserDefaults standardUserDefaults] floatForKey:MPOAuthTokenRefreshDateDefaultsKey];
 | 
			
		||||
		NSDate *tokenExpiryDate = [NSDate dateWithTimeIntervalSinceReferenceDate:expiryDateInterval];
 | 
			
		||||
			
 | 
			
		||||
		if ([tokenExpiryDate compare:[NSDate date]] == NSOrderedAscending) {
 | 
			
		||||
			[self refreshAccessToken];
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_authenticationRequestForRequestToken {
 | 
			
		||||
	if (oauthRequestTokenURL) {
 | 
			
		||||
		MPLog(@"--> Performing Request Token Request: %@", oauthRequestTokenURL);
 | 
			
		||||
		
 | 
			
		||||
		// Append the oauth_callbackUrl parameter for requesting the request token
 | 
			
		||||
		MPURLRequestParameter *callbackParameter = nil;
 | 
			
		||||
		if (delegate && [delegate respondsToSelector: @selector(callbackURLForCompletedUserAuthorization)]) {
 | 
			
		||||
			NSURL *callbackURL = [delegate callbackURLForCompletedUserAuthorization];
 | 
			
		||||
			callbackParameter = [[[MPURLRequestParameter alloc] initWithName:@"oauth_callback" andValue:[callbackURL absoluteString]] autorelease];
 | 
			
		||||
		} else {
 | 
			
		||||
			// oob = "Out of bounds"
 | 
			
		||||
			callbackParameter = [[[MPURLRequestParameter alloc] initWithName:@"oauth_callback" andValue:@"oob"] autorelease];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		NSArray *params = [NSArray arrayWithObject:callbackParameter];
 | 
			
		||||
		[[self oauthAPI] performMethod:nil atURL:oauthRequestTokenURL withParameters:params withTarget:self andAction:@selector(_authenticationRequestForRequestTokenSuccessfulLoad:withData:)];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_authenticationRequestForRequestTokenSuccessfulLoad:(MPOAuthAPIRequestLoader *)inLoader withData:(NSData *)inData {
 | 
			
		||||
	NSDictionary *oauthResponseParameters = inLoader.oauthResponse.oauthParameters;
 | 
			
		||||
	NSString *xoauthRequestAuthURL = [oauthResponseParameters objectForKey:@"xoauth_request_auth_url"]; // a common custom extension, used by Yahoo!
 | 
			
		||||
	NSURL *userAuthURL = xoauthRequestAuthURL ? [NSURL URLWithString:xoauthRequestAuthURL] : oauthAuthorizeTokenURL;
 | 
			
		||||
	NSURL *callbackURL = nil;
 | 
			
		||||
	
 | 
			
		||||
	if (!oauth10aModeActive) {
 | 
			
		||||
		callbackURL = [delegate respondsToSelector:@selector(callbackURLForCompletedUserAuthorization)] ? [delegate callbackURLForCompletedUserAuthorization] : nil;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:	[oauthResponseParameters objectForKey:	@"oauth_token"], @"oauth_token",
 | 
			
		||||
																													callbackURL, @"oauth_callback",
 | 
			
		||||
																													nil];
 | 
			
		||||
																						
 | 
			
		||||
	userAuthURL = [userAuthURL urlByAddingParameterDictionary:parameters];
 | 
			
		||||
	BOOL delegateWantsToBeInvolved = [delegate respondsToSelector:@selector(automaticallyRequestAuthenticationFromURL:withCallbackURL:)];
 | 
			
		||||
	
 | 
			
		||||
	if (!delegateWantsToBeInvolved || (delegateWantsToBeInvolved && [delegate automaticallyRequestAuthenticationFromURL:userAuthURL withCallbackURL:callbackURL])) {
 | 
			
		||||
		MPLog(@"--> Automatically Performing User Auth Request: %@", userAuthURL);
 | 
			
		||||
		[self _authenticationRequestForUserPermissionsConfirmationAtURL:userAuthURL];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)loader:(MPOAuthAPIRequestLoader *)inLoader didFailWithError:(NSError *)error {
 | 
			
		||||
	if ([delegate respondsToSelector:@selector(authenticationDidFailWithError:)]) {
 | 
			
		||||
		[delegate authenticationDidFailWithError: error];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_authenticationRequestForUserPermissionsConfirmationAtURL:(NSURL *)userAuthURL {
 | 
			
		||||
#if TARGET_OS_IPHONE
 | 
			
		||||
	[[UIApplication sharedApplication] openURL:userAuthURL];
 | 
			
		||||
#else
 | 
			
		||||
	[[NSWorkspace sharedWorkspace] openURL:userAuthURL];
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_authenticationRequestForAccessToken {
 | 
			
		||||
	NSArray *params = nil;
 | 
			
		||||
	
 | 
			
		||||
	if (delegate && [delegate respondsToSelector: @selector(oauthVerifierForCompletedUserAuthorization)]) {
 | 
			
		||||
		MPURLRequestParameter *verifierParameter = nil;
 | 
			
		||||
 | 
			
		||||
		NSString *verifier = [delegate oauthVerifierForCompletedUserAuthorization];
 | 
			
		||||
		if (verifier) {
 | 
			
		||||
			verifierParameter = [[[MPURLRequestParameter alloc] initWithName:@"oauth_verifier" andValue:verifier] autorelease];
 | 
			
		||||
			params = [NSArray arrayWithObject:verifierParameter];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (oauthGetAccessTokenURL) {
 | 
			
		||||
		MPLog(@"--> Performing Access Token Request: %@", oauthGetAccessTokenURL);
 | 
			
		||||
		[[self oauthAPI] performMethod:nil atURL:oauthGetAccessTokenURL withParameters:params withTarget:self andAction:nil];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)_requestTokenReceived:(NSNotification *)inNotification {
 | 
			
		||||
	if ([[inNotification userInfo] objectForKey:@"oauth_callback_confirmed"]) {
 | 
			
		||||
		oauth10aModeActive = YES;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[[self oauthAPI] setCredential:[[inNotification userInfo] objectForKey:@"oauth_token"] withName:kMPOAuthCredentialRequestToken];
 | 
			
		||||
	[[self oauthAPI] setCredential:[[inNotification userInfo] objectForKey:@"oauth_token_secret"] withName:kMPOAuthCredentialRequestTokenSecret];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_requestTokenRejected:(NSNotification *)inNotification {
 | 
			
		||||
	[[self oauthAPI] removeCredentialNamed:MPOAuthCredentialRequestTokenKey];
 | 
			
		||||
	[[self oauthAPI] removeCredentialNamed:MPOAuthCredentialRequestTokenSecretKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)_accessTokenReceived:(NSNotification *)inNotification {
 | 
			
		||||
	[[self oauthAPI] removeCredentialNamed:MPOAuthCredentialRequestTokenKey];
 | 
			
		||||
	[[self oauthAPI] removeCredentialNamed:MPOAuthCredentialRequestTokenSecretKey];
 | 
			
		||||
	
 | 
			
		||||
	[[self oauthAPI] setCredential:[[inNotification userInfo] objectForKey:@"oauth_token"] withName:kMPOAuthCredentialAccessToken];
 | 
			
		||||
	[[self oauthAPI] setCredential:[[inNotification userInfo] objectForKey:@"oauth_token_secret"] withName:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
	
 | 
			
		||||
	if ([[inNotification userInfo] objectForKey:MPOAuthCredentialSessionHandleKey]) {
 | 
			
		||||
		[[self oauthAPI] setCredential:[[inNotification userInfo] objectForKey:MPOAuthCredentialSessionHandleKey] withName:kMPOAuthCredentialSessionHandle];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[oauthAPI setAuthenticationState:MPOAuthAuthenticationStateAuthenticated];
 | 
			
		||||
	
 | 
			
		||||
	if ([[inNotification userInfo] objectForKey:@"oauth_expires_in"]) {
 | 
			
		||||
		NSTimeInterval tokenRefreshInterval = (NSTimeInterval)[[[inNotification userInfo] objectForKey:@"oauth_expires_in"] intValue];
 | 
			
		||||
		NSDate *tokenExpiryDate = [NSDate dateWithTimeIntervalSinceNow:tokenRefreshInterval];
 | 
			
		||||
		[[NSUserDefaults standardUserDefaults] setFloat:[tokenExpiryDate timeIntervalSinceReferenceDate] forKey:MPOAuthTokenRefreshDateDefaultsKey];
 | 
			
		||||
	
 | 
			
		||||
		if (tokenRefreshInterval > 0.0) {
 | 
			
		||||
			[self setTokenRefreshInterval:tokenRefreshInterval];
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		[[NSUserDefaults standardUserDefaults] removeObjectForKey:MPOAuthTokenRefreshDateDefaultsKey];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
#pragma mark - Private APIs -
 | 
			
		||||
 | 
			
		||||
- (void)_performedLoad:(MPOAuthAPIRequestLoader *)inLoader receivingData:(NSData *)inData {
 | 
			
		||||
	//	NSLog(@"loaded %@, and got %@", inLoader, inData);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthConnection.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthCredentialStore;
 | 
			
		||||
@protocol MPOAuthParameterFactory;
 | 
			
		||||
 | 
			
		||||
@class MPOAuthURLRequest;
 | 
			
		||||
@class MPOAuthURLResponse;
 | 
			
		||||
@class MPOAuthCredentialConcreteStore;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthConnection : NSURLConnection {
 | 
			
		||||
@private
 | 
			
		||||
	MPOAuthCredentialConcreteStore *credentials;
 | 
			
		||||
}
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials;
 | 
			
		||||
 | 
			
		||||
+ (MPOAuthConnection *)connectionWithRequest:(MPOAuthURLRequest *)inRequest delegate:(id)inDelegate credentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials;
 | 
			
		||||
+ (NSData *)sendSynchronousRequest:(MPOAuthURLRequest *)inRequest usingCredentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials returningResponse:(MPOAuthURLResponse **)outResponse error:(NSError **)inError;
 | 
			
		||||
- (id)initWithRequest:(MPOAuthURLRequest *)inRequest delegate:(id)inDelegate credentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthConnection.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthConnection.h"
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "MPOAuthURLResponse.h"
 | 
			
		||||
#import "MPOAuthParameterFactory.h"
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthConnection
 | 
			
		||||
 | 
			
		||||
+ (MPOAuthConnection *)connectionWithRequest:(MPOAuthURLRequest *)inRequest delegate:(id)inDelegate credentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials {
 | 
			
		||||
	MPOAuthConnection *aConnection = [[MPOAuthConnection alloc] initWithRequest:inRequest delegate:inDelegate credentials:inCredentials];
 | 
			
		||||
	return [aConnection autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSData *)sendSynchronousRequest:(MPOAuthURLRequest *)inRequest usingCredentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials returningResponse:(MPOAuthURLResponse **)outResponse error:(NSError **)inError {
 | 
			
		||||
	[inRequest addParameters:[inCredentials oauthParameters]];
 | 
			
		||||
	NSURLRequest *urlRequest = [inRequest urlRequestSignedWithSecret:[inCredentials signingKey] usingMethod:[inCredentials signatureMethod]];
 | 
			
		||||
	NSURLResponse *urlResponse = nil;
 | 
			
		||||
	NSData *responseData = [self sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:inError];
 | 
			
		||||
	MPOAuthURLResponse *oauthResponse = [[[MPOAuthURLResponse alloc] init] autorelease];
 | 
			
		||||
	[oauthResponse setResponse:urlResponse];
 | 
			
		||||
	*outResponse = oauthResponse;
 | 
			
		||||
	
 | 
			
		||||
	return responseData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithRequest:(MPOAuthURLRequest *)inRequest delegate:(id)inDelegate credentials:(NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> *)inCredentials {
 | 
			
		||||
	[inRequest addParameters:[inCredentials oauthParameters]];
 | 
			
		||||
	NSURLRequest *urlRequest = [inRequest urlRequestSignedWithSecret:[inCredentials signingKey] usingMethod:[inCredentials signatureMethod]];
 | 
			
		||||
	if ((self = [super initWithRequest:urlRequest delegate:inDelegate])) {
 | 
			
		||||
		credentials = [inCredentials retain];
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[credentials release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id<MPOAuthCredentialStore,MPOAuthParameterFactory>)credentials {
 | 
			
		||||
	return credentials;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialConcreteStore+TokenAdditionsMac.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.13.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore+KeychainAdditions.h"
 | 
			
		||||
#import <Security/Security.h>
 | 
			
		||||
 | 
			
		||||
#if !TARGET_OS_IPHONE || (TARGET_IPHONE_SIMULATOR && !__IPHONE_3_0)
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthCredentialConcreteStore (KeychainAdditionsMac)
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName returningItem:(SecKeychainItemRef *)outKeychainItemRef;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthCredentialConcreteStore (KeychainAdditions)
 | 
			
		||||
 | 
			
		||||
- (void)addToKeychainUsingName:(NSString *)inName andValue:(NSString *)inValue {
 | 
			
		||||
	NSString *serverName = [[self baseURL] host];
 | 
			
		||||
	NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
 | 
			
		||||
	NSString *securityDomain = [[self authenticationURL] host];
 | 
			
		||||
	NSString *uniqueName = [NSString stringWithFormat:@"%@.%@", bundleID, inName];
 | 
			
		||||
	SecKeychainItemRef existingKeychainItem = NULL;
 | 
			
		||||
	
 | 
			
		||||
	if ([self findValueFromKeychainUsingName:inName returningItem:&existingKeychainItem]) {
 | 
			
		||||
		// This is MUCH easier than updating the item attributes/data
 | 
			
		||||
		SecKeychainItemDelete(existingKeychainItem);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	SecKeychainAddInternetPassword(NULL /* default keychain */,
 | 
			
		||||
								   [serverName length], [serverName UTF8String],
 | 
			
		||||
								   [securityDomain length], [securityDomain UTF8String],
 | 
			
		||||
								   [uniqueName length], [uniqueName UTF8String],	/* account name */
 | 
			
		||||
								   0, NULL,	/* path */
 | 
			
		||||
								   0,
 | 
			
		||||
								   'oaut'	/* OAuth, not an official OSType code */,
 | 
			
		||||
								   kSecAuthenticationTypeDefault,
 | 
			
		||||
								   [inValue length], [inValue UTF8String],
 | 
			
		||||
								   NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName {
 | 
			
		||||
	return [self findValueFromKeychainUsingName:inName returningItem:NULL];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName returningItem:(SecKeychainItemRef *)outKeychainItemRef {
 | 
			
		||||
	NSString *foundPassword = nil;
 | 
			
		||||
	NSString *serverName = [[self baseURL] host];
 | 
			
		||||
	NSString *securityDomain = [[self authenticationURL] host];
 | 
			
		||||
	NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
 | 
			
		||||
	NSString *uniqueName = [NSString stringWithFormat:@"%@.%@", bundleID, inName];
 | 
			
		||||
	
 | 
			
		||||
	UInt32 passwordLength = 0;
 | 
			
		||||
	const char *passwordString = NULL;
 | 
			
		||||
	
 | 
			
		||||
	OSStatus status = SecKeychainFindInternetPassword(NULL	/* default keychain */,
 | 
			
		||||
													  [serverName length], [serverName UTF8String],
 | 
			
		||||
													  [securityDomain length], [securityDomain UTF8String],
 | 
			
		||||
													  [uniqueName length], [uniqueName UTF8String],
 | 
			
		||||
													  0, NULL,	/* path */
 | 
			
		||||
													  0,
 | 
			
		||||
													  'oaut',
 | 
			
		||||
													  kSecAuthenticationTypeDefault,
 | 
			
		||||
													  (UInt32 *)&passwordLength,
 | 
			
		||||
													  (void **)&passwordString,
 | 
			
		||||
													  outKeychainItemRef);
 | 
			
		||||
	
 | 
			
		||||
	if (status == noErr && passwordLength) {
 | 
			
		||||
		NSData *passwordStringData = [NSData dataWithBytes:passwordString length:passwordLength];
 | 
			
		||||
		foundPassword = [[NSString alloc] initWithData:passwordStringData encoding:NSUTF8StringEncoding];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return [foundPassword autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeValueFromKeychainUsingName:(NSString *)inName {
 | 
			
		||||
	SecKeychainItemRef aKeychainItem = NULL;
 | 
			
		||||
	
 | 
			
		||||
	[self findValueFromKeychainUsingName:inName returningItem:&aKeychainItem];
 | 
			
		||||
	
 | 
			
		||||
	if (aKeychainItem) {
 | 
			
		||||
		SecKeychainItemDelete(aKeychainItem);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialConcreteStore+TokenAdditionsMac.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.13.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthCredentialConcreteStore (KeychainAdditions)
 | 
			
		||||
 | 
			
		||||
- (void)addToKeychainUsingName:(NSString *)inName andValue:(NSString *)inValue;
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName;
 | 
			
		||||
- (void)removeValueFromKeychainUsingName:(NSString *)inName;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,112 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialConcreteStore+TokenAdditionsiPhone.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.13.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore+KeychainAdditions.h"
 | 
			
		||||
#import <Security/Security.h>
 | 
			
		||||
 | 
			
		||||
#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || __IPHONE_3_0)
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthCredentialConcreteStore (TokenAdditionsiPhone)
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName returningItem:(NSDictionary **)outKeychainItemRef;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthCredentialConcreteStore (KeychainAdditions)
 | 
			
		||||
 | 
			
		||||
- (void)addToKeychainUsingName:(NSString *)inName andValue:(NSString *)inValue {
 | 
			
		||||
	NSString *serverName = [[self baseURL] host];
 | 
			
		||||
	NSString *securityDomain = [[self authenticationURL] host];
 | 
			
		||||
//	NSString *itemID = [NSString stringWithFormat:@"%@.oauth.%@", [[NSBundle mainBundle] bundleIdentifier], inName];
 | 
			
		||||
	NSDictionary *searchDictionary = nil;
 | 
			
		||||
	NSDictionary *keychainItemAttributeDictionary = [NSDictionary dictionaryWithObjectsAndKeys:	(id)kSecClassInternetPassword, kSecClass,
 | 
			
		||||
																								securityDomain, kSecAttrSecurityDomain,
 | 
			
		||||
																								serverName, kSecAttrServer,
 | 
			
		||||
																								inName, kSecAttrAccount,
 | 
			
		||||
																								kSecAttrAuthenticationTypeDefault, kSecAttrAuthenticationType,
 | 
			
		||||
																								[NSNumber numberWithUnsignedLongLong:'oaut'], kSecAttrType,
 | 
			
		||||
																								[inValue dataUsingEncoding:NSUTF8StringEncoding], kSecValueData,
 | 
			
		||||
													 nil];
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	if ([self findValueFromKeychainUsingName:inName returningItem:&searchDictionary]) {
 | 
			
		||||
		NSMutableDictionary *updateDictionary = [keychainItemAttributeDictionary mutableCopy];
 | 
			
		||||
		[updateDictionary removeObjectForKey:(id)kSecClass];
 | 
			
		||||
		
 | 
			
		||||
		SecItemUpdate((CFDictionaryRef)keychainItemAttributeDictionary, (CFDictionaryRef)updateDictionary);
 | 
			
		||||
		[updateDictionary release];
 | 
			
		||||
	} else {
 | 
			
		||||
		OSStatus success = SecItemAdd( (CFDictionaryRef)keychainItemAttributeDictionary, NULL);
 | 
			
		||||
		
 | 
			
		||||
		if (success == errSecNotAvailable) {
 | 
			
		||||
			[NSException raise:@"Keychain Not Available" format:@"Keychain Access Not Currently Available"];
 | 
			
		||||
		} else if (success == errSecDuplicateItem) {
 | 
			
		||||
			[NSException raise:@"Keychain duplicate item exception" format:@"Item already exists for %@", keychainItemAttributeDictionary];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName {
 | 
			
		||||
	return [self findValueFromKeychainUsingName:inName returningItem:NULL];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)findValueFromKeychainUsingName:(NSString *)inName returningItem:(NSDictionary **)outKeychainItemRef {
 | 
			
		||||
	NSString *foundPassword = nil;
 | 
			
		||||
	NSString *serverName = [[self baseURL] host];
 | 
			
		||||
	NSString *securityDomain = [[self authenticationURL] host];
 | 
			
		||||
	NSDictionary *attributesDictionary = nil;
 | 
			
		||||
	NSData *foundValue = nil;
 | 
			
		||||
	OSStatus status = noErr;
 | 
			
		||||
//	NSString *itemID = [NSString stringWithFormat:@"%@.oauth.%@", [[NSBundle mainBundle] bundleIdentifier], inName];
 | 
			
		||||
	
 | 
			
		||||
	NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassInternetPassword, (id)kSecClass,
 | 
			
		||||
																							  securityDomain, (id)kSecAttrSecurityDomain,
 | 
			
		||||
																							  serverName, (id)kSecAttrServer,
 | 
			
		||||
																							  inName, (id)kSecAttrAccount,
 | 
			
		||||
																							  (id)kSecMatchLimitOne, (id)kSecMatchLimit,
 | 
			
		||||
																							  (id)kCFBooleanTrue, (id)kSecReturnData,
 | 
			
		||||
																							  (id)kCFBooleanTrue, (id)kSecReturnAttributes,
 | 
			
		||||
																							  (id)kCFBooleanTrue, (id)kSecReturnPersistentRef,
 | 
			
		||||
											 nil];
 | 
			
		||||
 | 
			
		||||
	status = SecItemCopyMatching((CFDictionaryRef)searchDictionary, (CFTypeRef *)&attributesDictionary);		
 | 
			
		||||
	foundValue = [attributesDictionary objectForKey:(id)kSecValueData];
 | 
			
		||||
	if (outKeychainItemRef) {
 | 
			
		||||
		*outKeychainItemRef = attributesDictionary;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (status == noErr && foundValue) {
 | 
			
		||||
		foundPassword = [[NSString alloc] initWithData:foundValue encoding:NSUTF8StringEncoding];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return [foundPassword autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeValueFromKeychainUsingName:(NSString *)inName {
 | 
			
		||||
	NSString *serverName = [[self baseURL] host];
 | 
			
		||||
	NSString *securityDomain = [[self authenticationURL] host];
 | 
			
		||||
 | 
			
		||||
	NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:	(id)kSecClassInternetPassword, (id)kSecClass,
 | 
			
		||||
																								 securityDomain, (id)kSecAttrSecurityDomain,
 | 
			
		||||
																								 serverName, (id)kSecAttrServer,
 | 
			
		||||
																								 inName, (id)kSecAttrAccount,
 | 
			
		||||
																								 nil];
 | 
			
		||||
	
 | 
			
		||||
	OSStatus success = SecItemDelete((CFDictionaryRef)searchDictionary);
 | 
			
		||||
 | 
			
		||||
	if (success == errSecNotAvailable) {
 | 
			
		||||
		[NSException raise:@"Keychain Not Available" format:@"Keychain Access Not Currently Available"];
 | 
			
		||||
	} else if (success == errSecParam) {
 | 
			
		||||
		[NSException raise:@"Keychain parameter error" format:@"One or more parameters passed to the function were not valid from %@", searchDictionary];
 | 
			
		||||
	} else if (success == errSecAllocate) {
 | 
			
		||||
		[NSException raise:@"Keychain memory error" format:@"Failed to allocate memory"];			
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialConcreteStore.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.11.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "MPOAuthCredentialStore.h"
 | 
			
		||||
#import "MPOAuthParameterFactory.h"
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthCredentialConcreteStore : NSObject <MPOAuthCredentialStore, MPOAuthParameterFactory> {
 | 
			
		||||
	NSMutableDictionary *store;
 | 
			
		||||
	NSURL				*baseURL;
 | 
			
		||||
	NSURL				*authenticationURL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setStore:(NSMutableDictionary *)theStore;
 | 
			
		||||
- (NSMutableDictionary *)store;
 | 
			
		||||
- (void)setBaseURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)baseURL;
 | 
			
		||||
- (void)setAuthenticationURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)authenticationURL;
 | 
			
		||||
 | 
			
		||||
- (NSString *)tokenSecret;
 | 
			
		||||
- (NSString *)signingKey;
 | 
			
		||||
 | 
			
		||||
- (void)setRequestToken:(NSString *)theToken;
 | 
			
		||||
- (NSString *)requestToken;
 | 
			
		||||
- (void)setRequestTokenSecret:(NSString *)theSecret;
 | 
			
		||||
- (NSString *)requestTokenSecret;
 | 
			
		||||
- (void)setAccessToken:(NSString *)theToken;
 | 
			
		||||
- (NSString *)accessToken;
 | 
			
		||||
- (void)setAccessTokenSecret:(NSString *)theSecret;
 | 
			
		||||
- (NSString *)accessTokenSecret;
 | 
			
		||||
 | 
			
		||||
- (void)setSessionHandle:(NSString *)theHandle;
 | 
			
		||||
- (NSString *)sessionHandle;
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredential;
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials forBaseURL:(NSURL *)inBaseURL;
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials forBaseURL:(NSURL *)inBaseURL withAuthenticationURL:(NSURL *)inAuthenticationURL;
 | 
			
		||||
 | 
			
		||||
- (void)setCredential:(id)inCredential withName:(NSString *)inName;
 | 
			
		||||
- (void)removeCredentialNamed:(NSString *)inName;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,295 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialConcreteStore.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.11.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthCredentialConcreteStore+KeychainAdditions.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
extern NSString * const MPOAuthCredentialRequestTokenKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialRequestTokenSecretKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialAccessTokenKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialAccessTokenSecretKey;
 | 
			
		||||
extern NSString * const MPOAuthCredentialSessionHandleKey;
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthCredentialConcreteStore
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials {
 | 
			
		||||
    return [self initWithCredentials:inCredentials forBaseURL:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials forBaseURL:(NSURL *)inBaseURL {
 | 
			
		||||
	return [self initWithCredentials:inCredentials forBaseURL:inBaseURL withAuthenticationURL:inBaseURL];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithCredentials:(NSDictionary *)inCredentials forBaseURL:(NSURL *)inBaseURL withAuthenticationURL:(NSURL *)inAuthenticationURL {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		store = [[NSMutableDictionary alloc] initWithDictionary:inCredentials];
 | 
			
		||||
		[self setBaseURL:inBaseURL];
 | 
			
		||||
		[self setAuthenticationURL:inAuthenticationURL];
 | 
			
		||||
    }
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[store release];
 | 
			
		||||
	[baseURL release];
 | 
			
		||||
	[authenticationURL release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setStore:(NSMutableDictionary *)theStore {
 | 
			
		||||
	[store release];
 | 
			
		||||
	store = [theStore retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSMutableDictionary *)store {
 | 
			
		||||
	return store;
 | 
			
		||||
}
 | 
			
		||||
- (void)setBaseURL:(NSURL *)theURL {
 | 
			
		||||
	[baseURL release];
 | 
			
		||||
	baseURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)baseURL {
 | 
			
		||||
	return baseURL;
 | 
			
		||||
}
 | 
			
		||||
- (void)setAuthenticationURL:(NSURL *)theURL {
 | 
			
		||||
	[authenticationURL release];
 | 
			
		||||
	authenticationURL = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)authenticationURL {
 | 
			
		||||
	return authenticationURL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSString *)consumerKey {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialConsumerKey];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)consumerSecret {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialConsumerSecret];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)username {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialUsername];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)password {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialPassword];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)requestToken {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialRequestToken];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setRequestToken:(NSString *)inToken {
 | 
			
		||||
	if (inToken) {
 | 
			
		||||
		[store setObject:inToken forKey:kMPOAuthCredentialRequestToken];
 | 
			
		||||
	} else {
 | 
			
		||||
		[store removeObjectForKey:kMPOAuthCredentialRequestToken];
 | 
			
		||||
		[self removeValueFromKeychainUsingName:kMPOAuthCredentialRequestToken];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)requestTokenSecret {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialRequestTokenSecret];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setRequestTokenSecret:(NSString *)inTokenSecret {
 | 
			
		||||
	if (inTokenSecret) {
 | 
			
		||||
		[store setObject:inTokenSecret forKey:kMPOAuthCredentialRequestTokenSecret];
 | 
			
		||||
	} else {
 | 
			
		||||
		[store removeObjectForKey:kMPOAuthCredentialRequestTokenSecret];
 | 
			
		||||
		[self removeValueFromKeychainUsingName:kMPOAuthCredentialRequestTokenSecret];
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)accessToken {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialAccessToken];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAccessToken:(NSString *)inToken {
 | 
			
		||||
	if (inToken) {
 | 
			
		||||
		[store setObject:inToken forKey:kMPOAuthCredentialAccessToken];
 | 
			
		||||
	} else {
 | 
			
		||||
		[store removeObjectForKey:kMPOAuthCredentialAccessToken];
 | 
			
		||||
		[self removeValueFromKeychainUsingName:kMPOAuthCredentialAccessToken];
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)accessTokenSecret {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setAccessTokenSecret:(NSString *)inTokenSecret {
 | 
			
		||||
	if (inTokenSecret) {
 | 
			
		||||
		[store setObject:inTokenSecret forKey:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
	} else {
 | 
			
		||||
		[store removeObjectForKey:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
		[self removeValueFromKeychainUsingName:kMPOAuthCredentialAccessTokenSecret];
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)sessionHandle {
 | 
			
		||||
	return [store objectForKey:kMPOAuthCredentialSessionHandle];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setSessionHandle:(NSString *)inSessionHandle {
 | 
			
		||||
	if (inSessionHandle) {
 | 
			
		||||
		[store setObject:inSessionHandle forKey:kMPOAuthCredentialSessionHandle];
 | 
			
		||||
	} else {
 | 
			
		||||
		[store removeObjectForKey:kMPOAuthCredentialSessionHandle];
 | 
			
		||||
		[self removeValueFromKeychainUsingName:kMPOAuthCredentialSessionHandle];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSString *)credentialNamed:(NSString *)inCredentialName {
 | 
			
		||||
	return [store objectForKey:inCredentialName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setCredential:(id)inCredential withName:(NSString *)inName {
 | 
			
		||||
	[store setObject:inCredential forKey:inName];
 | 
			
		||||
	[self addToKeychainUsingName:inName andValue:inCredential];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)removeCredentialNamed:(NSString *)inName {
 | 
			
		||||
	[store removeObjectForKey:inName];
 | 
			
		||||
	[self removeValueFromKeychainUsingName:inName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)discardOAuthCredentials {
 | 
			
		||||
	[self setRequestToken:nil];
 | 
			
		||||
	[self setRequestTokenSecret:nil];
 | 
			
		||||
	[self setAccessToken:nil];
 | 
			
		||||
	[self setAccessTokenSecret:nil];
 | 
			
		||||
	[self setSessionHandle:nil];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSString *)tokenSecret {
 | 
			
		||||
	NSString *tokenSecret = @"";
 | 
			
		||||
	
 | 
			
		||||
	if ([self accessToken]) {
 | 
			
		||||
		tokenSecret = [self accessTokenSecret];
 | 
			
		||||
	} else if ([self requestToken]) {
 | 
			
		||||
		tokenSecret = [self requestTokenSecret];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return tokenSecret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)signingKey {
 | 
			
		||||
	NSString *consumerSecret = [[self consumerSecret] stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
	NSString *tokenSecret = [[self tokenSecret] stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
	
 | 
			
		||||
	return [NSString stringWithFormat:@"%@%&%@", consumerSecret, tokenSecret];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSString *)timestamp {
 | 
			
		||||
	return [NSString stringWithFormat:@"%d", (int)[[NSDate date] timeIntervalSince1970]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)signatureMethod {
 | 
			
		||||
	return [store objectForKey:kMPOAuthSignatureMethod];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSArray *)oauthParameters {
 | 
			
		||||
	NSMutableArray *oauthParameters = [[NSMutableArray alloc] initWithCapacity:5];	
 | 
			
		||||
	MPURLRequestParameter *tokenParameter = [self oauthTokenParameter];
 | 
			
		||||
	
 | 
			
		||||
	[oauthParameters addObject:[self oauthConsumerKeyParameter]];
 | 
			
		||||
	if (tokenParameter) [oauthParameters addObject:tokenParameter];
 | 
			
		||||
	[oauthParameters addObject:[self oauthSignatureMethodParameter]];
 | 
			
		||||
	[oauthParameters addObject:[self oauthTimestampParameter]];
 | 
			
		||||
	[oauthParameters addObject:[self oauthNonceParameter]];
 | 
			
		||||
	[oauthParameters addObject:[self oauthVersionParameter]];
 | 
			
		||||
	
 | 
			
		||||
	return [oauthParameters autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setSignatureMethod:(NSString *)inSignatureMethod {
 | 
			
		||||
	[store setObject:inSignatureMethod forKey:kMPOAuthSignatureMethod];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthConsumerKeyParameter {
 | 
			
		||||
	MPURLRequestParameter *aRequestParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
	aRequestParameter.name = @"oauth_consumer_key";
 | 
			
		||||
	aRequestParameter.value = [self consumerKey];
 | 
			
		||||
	
 | 
			
		||||
	return [aRequestParameter autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthTokenParameter {
 | 
			
		||||
	MPURLRequestParameter *aRequestParameter = nil;
 | 
			
		||||
	
 | 
			
		||||
	if ([self accessToken] || [self requestToken]) {
 | 
			
		||||
		aRequestParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
		aRequestParameter.name = @"oauth_token";
 | 
			
		||||
		
 | 
			
		||||
		if ([self accessToken]) {
 | 
			
		||||
			aRequestParameter.value = [self accessToken];
 | 
			
		||||
		} else if ([self requestToken]) {
 | 
			
		||||
			aRequestParameter.value = [self requestToken];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return [aRequestParameter autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthSignatureMethodParameter {
 | 
			
		||||
	MPURLRequestParameter *aRequestParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
	aRequestParameter.name = @"oauth_signature_method";
 | 
			
		||||
	aRequestParameter.value = [self signatureMethod];
 | 
			
		||||
	
 | 
			
		||||
	return [aRequestParameter autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthTimestampParameter {
 | 
			
		||||
	MPURLRequestParameter *aRequestParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
	aRequestParameter.name = @"oauth_timestamp";
 | 
			
		||||
	aRequestParameter.value = [self timestamp];
 | 
			
		||||
	
 | 
			
		||||
	return [aRequestParameter autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthNonceParameter {
 | 
			
		||||
	MPURLRequestParameter *aRequestParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
	aRequestParameter.name = @"oauth_nonce";
 | 
			
		||||
	
 | 
			
		||||
	NSString *generatedNonce = nil;
 | 
			
		||||
	CFUUIDRef generatedUUID = CFUUIDCreate(kCFAllocatorDefault);
 | 
			
		||||
	
 | 
			
		||||
	generatedNonce = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, generatedUUID);
 | 
			
		||||
	CFRelease(generatedUUID);
 | 
			
		||||
	
 | 
			
		||||
	aRequestParameter.value = generatedNonce;
 | 
			
		||||
	[generatedNonce release];
 | 
			
		||||
	
 | 
			
		||||
	return [aRequestParameter autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthVersionParameter {
 | 
			
		||||
	MPURLRequestParameter *versionParameter = [store objectForKey:@"versionParameter"];
 | 
			
		||||
	
 | 
			
		||||
	if (!versionParameter) {
 | 
			
		||||
		versionParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
		versionParameter.name = @"oauth_version";
 | 
			
		||||
		versionParameter.value = @"1.0";
 | 
			
		||||
		[versionParameter autorelease];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return versionParameter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthCredentialStore.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.06.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
extern NSString *kMPOAuthCredentialConsumerKey;
 | 
			
		||||
extern NSString *kMPOAuthCredentialConsumerSecret;
 | 
			
		||||
extern NSString *kMPOAuthCredentialUsername;
 | 
			
		||||
extern NSString *kMPOAuthCredentialPassword;
 | 
			
		||||
extern NSString *kMPOAuthCredentialRequestToken;
 | 
			
		||||
extern NSString *kMPOAuthCredentialRequestTokenSecret;
 | 
			
		||||
extern NSString *kMPOAuthCredentialAccessToken;
 | 
			
		||||
extern NSString *kMPOAuthCredentialAccessTokenSecret;
 | 
			
		||||
extern NSString *kMPOAuthCredentialSessionHandle;
 | 
			
		||||
extern NSString *kMPOAuthCredentialRealm;
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthCredentialStore <NSObject>
 | 
			
		||||
 | 
			
		||||
- (NSString *)consumerKey;
 | 
			
		||||
- (NSString *)consumerSecret;
 | 
			
		||||
- (NSString *)username;
 | 
			
		||||
- (NSString *)password;
 | 
			
		||||
- (NSString *)requestToken;
 | 
			
		||||
- (NSString *)requestTokenSecret;
 | 
			
		||||
- (NSString *)accessToken;
 | 
			
		||||
- (NSString *)accessTokenSecret;
 | 
			
		||||
 | 
			
		||||
- (NSString *)credentialNamed:(NSString *)inCredentialName;
 | 
			
		||||
- (void)discardOAuthCredentials;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthParameterFactory.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.06.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
extern NSString *kMPOAuthSignatureMethod;
 | 
			
		||||
 | 
			
		||||
@class MPURLRequestParameter;
 | 
			
		||||
 | 
			
		||||
@protocol MPOAuthParameterFactory <NSObject>
 | 
			
		||||
 | 
			
		||||
- (void)setSignatureMethod:(NSString *)theMethod;
 | 
			
		||||
- (NSString *)signatureMethod;
 | 
			
		||||
- (NSString *)signingKey;
 | 
			
		||||
- (NSString *)timestamp;
 | 
			
		||||
 | 
			
		||||
- (NSArray *)oauthParameters;
 | 
			
		||||
 | 
			
		||||
- (MPURLRequestParameter *)oauthConsumerKeyParameter;
 | 
			
		||||
- (MPURLRequestParameter *)oauthTokenParameter;
 | 
			
		||||
- (MPURLRequestParameter *)oauthSignatureMethodParameter;
 | 
			
		||||
- (MPURLRequestParameter *)oauthTimestampParameter;
 | 
			
		||||
- (MPURLRequestParameter *)oauthNonceParameter;
 | 
			
		||||
- (MPURLRequestParameter *)oauthVersionParameter;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthSignatureParameter.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.07.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
 | 
			
		||||
#define kMPOAuthSignatureMethodPlaintext	@"PLAINTEXT"
 | 
			
		||||
#define kMPOAuthSignatureMethodHMACSHA1		@"HMAC-SHA1"
 | 
			
		||||
#define kMPOAuthSignatureMethodRSASHA1		@"RSA-SHA1"
 | 
			
		||||
 | 
			
		||||
@class MPOAuthURLRequest;
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthSignatureParameter : MPURLRequestParameter {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)signatureBaseStringUsingParameterString:(NSString *)inParameterString forRequest:(MPOAuthURLRequest *)inRequest;
 | 
			
		||||
+ (NSString *)HMAC_SHA1SignatureForText:(NSString *)inText usingSecret:(NSString *)inSecret;
 | 
			
		||||
 | 
			
		||||
- (id)initWithText:(NSString *)inText andSecret:(NSString *)inSecret forRequest:(MPOAuthURLRequest *)inRequest usingMethod:(NSString *)inMethod;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,95 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthSignatureParameter.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.07.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthSignatureParameter.h"
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
 | 
			
		||||
#import <openssl/evp.h>
 | 
			
		||||
#include <openssl/hmac.h>
 | 
			
		||||
#include <openssl/sha.h>
 | 
			
		||||
#include "Base64Transcoder.h"
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthSignatureParameter ()
 | 
			
		||||
- (id)initUsingHMAC_SHA1WithText:(NSString *)inText andSecret:(NSString *)inSecret forRequest:(MPOAuthURLRequest *)inRequest;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthSignatureParameter
 | 
			
		||||
 | 
			
		||||
+ (NSString *)signatureBaseStringUsingParameterString:(NSString *)inParameterString forRequest:(MPOAuthURLRequest *)inRequest {
 | 
			
		||||
	return [NSString stringWithFormat:@"%@&%@&%@",	[inRequest HTTPMethod],
 | 
			
		||||
			[[inRequest.url absoluteNormalizedString] stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding],
 | 
			
		||||
			[inParameterString stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)HMAC_SHA1SignatureForText:(NSString *)inText usingSecret:(NSString *)inSecret {
 | 
			
		||||
	NSData *secretData = [inSecret dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
	NSData *textData = [inText dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
	OpenSSL_add_all_algorithms();
 | 
			
		||||
	unsigned char outbuf[SHA_DIGEST_LENGTH];
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	unsigned int templen;
 | 
			
		||||
	HMAC_CTX ctx;
 | 
			
		||||
	
 | 
			
		||||
	const EVP_MD *digest = EVP_sha1();
 | 
			
		||||
	if(!digest) {
 | 
			
		||||
		NSLog(@"cannot get digest with name SHA1");
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	HMAC_CTX_init(&ctx);
 | 
			
		||||
	HMAC_Init(&ctx, [secretData bytes], [secretData length], digest);
 | 
			
		||||
	HMAC_Update(&ctx, [textData bytes], [textData length]);
 | 
			
		||||
	HMAC_Final(&ctx, outbuf, &templen);
 | 
			
		||||
	HMAC_CTX_cleanup(&ctx);
 | 
			
		||||
	
 | 
			
		||||
	//Base64 Encoding
 | 
			
		||||
	char base64Result[32];
 | 
			
		||||
	size_t theResultLength = 32;
 | 
			
		||||
	Base64EncodeData(outbuf, 20, base64Result, &theResultLength);
 | 
			
		||||
	NSData *theData = [NSData dataWithBytes:base64Result length:theResultLength];
 | 
			
		||||
	NSString *base64EncodedResult = [[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease];
 | 
			
		||||
	
 | 
			
		||||
	return base64EncodedResult;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithText:(NSString *)inText andSecret:(NSString *)inSecret forRequest:(MPOAuthURLRequest *)inRequest usingMethod:(NSString *)inMethod {
 | 
			
		||||
	if ([inMethod isEqual:kMPOAuthSignatureMethodHMACSHA1]) {
 | 
			
		||||
		self = [self initUsingHMAC_SHA1WithText:inText andSecret:inSecret forRequest:inRequest];
 | 
			
		||||
	} else if ([inMethod isEqualToString:kMPOAuthSignatureMethodPlaintext]) {
 | 
			
		||||
		if ((self = [super init])) {
 | 
			
		||||
			[self setName:@"oauth_signature"];
 | 
			
		||||
			[self setValue:inSecret];
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		[self release];
 | 
			
		||||
		self = nil;
 | 
			
		||||
		[NSException raise:@"Unsupported Signature Method" format:@"The signature method \"%@\" is not currently support by MPOAuthConnection", inMethod];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initUsingHMAC_SHA1WithText:(NSString *)inText andSecret:(NSString *)inSecret forRequest:(MPOAuthURLRequest *)inRequest {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		NSString *signatureBaseString = [MPOAuthSignatureParameter signatureBaseStringUsingParameterString:inText forRequest:inRequest];
 | 
			
		||||
 | 
			
		||||
		[self setName:@"oauth_signature"];
 | 
			
		||||
		[self setValue:[MPOAuthSignatureParameter HMAC_SHA1SignatureForText:signatureBaseString usingSecret:inSecret]];
 | 
			
		||||
	}
 | 
			
		||||
	return self;	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthURLRequest.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthURLRequest : NSObject {
 | 
			
		||||
@private
 | 
			
		||||
	NSURL			*url;
 | 
			
		||||
	NSString		*HTTPMethod;
 | 
			
		||||
	NSURLRequest	*urlRequest;
 | 
			
		||||
	NSMutableArray	*parameters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setURL:(NSURL *)theURL;
 | 
			
		||||
- (NSURL *)url;
 | 
			
		||||
- (void)setHTTPMethod:(NSString *)theMethod;
 | 
			
		||||
- (NSString *)HTTPMethod;
 | 
			
		||||
- (void)setURLRequest:(NSURLRequest *)theRequest;
 | 
			
		||||
- (NSURLRequest *)urlRequest;
 | 
			
		||||
- (void)setParameters:(NSMutableArray *)theParameters;
 | 
			
		||||
- (NSMutableArray *)parameters;
 | 
			
		||||
 | 
			
		||||
- (id)initWithURL:(NSURL *)inURL andParameters:(NSArray *)parameters;
 | 
			
		||||
- (id)initWithURLRequest:(NSURLRequest *)inRequest;
 | 
			
		||||
 | 
			
		||||
- (void)addParameters:(NSArray *)inParameters;
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)urlRequestSignedWithSecret:(NSString *)inSecret usingMethod:(NSString *)inScheme;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,119 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthURLRequest.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthURLRequest.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "MPOAuthSignatureParameter.h"
 | 
			
		||||
#import "MPDebug.h"
 | 
			
		||||
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthURLRequest
 | 
			
		||||
 | 
			
		||||
- (id)initWithURL:(NSURL *)inURL andParameters:(NSArray *)inParameters {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		url = [inURL retain];
 | 
			
		||||
		parameters = inParameters ? [inParameters mutableCopy] : [[NSMutableArray alloc] initWithCapacity:10];
 | 
			
		||||
		[self setHTTPMethod:@"GET"];
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithURLRequest:(NSURLRequest *)inRequest {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		url = [[[inRequest URL] urlByRemovingQuery] retain];
 | 
			
		||||
		parameters = [[MPURLRequestParameter parametersFromString:[[inRequest URL] query]] mutableCopy];
 | 
			
		||||
		[self setHTTPMethod:[inRequest HTTPMethod]];
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[url release];
 | 
			
		||||
	[HTTPMethod release];
 | 
			
		||||
	[urlRequest release];
 | 
			
		||||
	[parameters release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setURL:(NSURL *)theURL {
 | 
			
		||||
	[url release];
 | 
			
		||||
	url = [theURL retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURL *)url {
 | 
			
		||||
	return url;
 | 
			
		||||
}
 | 
			
		||||
- (void)setHTTPMethod:(NSString *)theMethod {
 | 
			
		||||
	[HTTPMethod release];
 | 
			
		||||
	HTTPMethod = [theMethod retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)HTTPMethod {
 | 
			
		||||
	return HTTPMethod;
 | 
			
		||||
}
 | 
			
		||||
- (void)setURLRequest:(NSURLRequest *)theRequest {
 | 
			
		||||
	[urlRequest release];
 | 
			
		||||
	urlRequest = [theRequest retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURLRequest *)urlRequest {
 | 
			
		||||
	return urlRequest;
 | 
			
		||||
}
 | 
			
		||||
- (void)setParameters:(NSMutableArray *)theParameters {
 | 
			
		||||
	[parameters release];
 | 
			
		||||
	parameters = [theParameters retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSMutableArray *)parameters {
 | 
			
		||||
	return parameters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSMutableURLRequest*)urlRequestSignedWithSecret:(NSString *)inSecret usingMethod:(NSString *)inScheme {
 | 
			
		||||
	[parameters sortUsingSelector:@selector(compare:)];
 | 
			
		||||
 | 
			
		||||
	NSMutableURLRequest *aRequest = [[NSMutableURLRequest alloc] init];
 | 
			
		||||
	NSMutableString *parameterString = [[NSMutableString alloc] initWithString:[MPURLRequestParameter parameterStringForParameters:parameters]];
 | 
			
		||||
	MPOAuthSignatureParameter *signatureParameter = [[MPOAuthSignatureParameter alloc] initWithText:parameterString andSecret:inSecret forRequest:self usingMethod:inScheme];
 | 
			
		||||
	[parameterString appendFormat:@"&%@", [signatureParameter URLEncodedParameterString]];
 | 
			
		||||
	
 | 
			
		||||
	[aRequest setHTTPMethod:HTTPMethod];
 | 
			
		||||
	
 | 
			
		||||
	if ([[self HTTPMethod] isEqualToString:@"GET"] && [parameters count]) {
 | 
			
		||||
		NSString *urlString = [NSString stringWithFormat:@"%@?%@", [url absoluteString], parameterString];
 | 
			
		||||
		MPLog( @"urlString - %@", urlString);
 | 
			
		||||
		
 | 
			
		||||
		[aRequest setURL:[NSURL URLWithString:urlString]];
 | 
			
		||||
	} else if ([[self HTTPMethod] isEqualToString:@"POST"]) {
 | 
			
		||||
		NSData *postData = [parameterString dataUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
		MPLog(@"urlString - %@", url);
 | 
			
		||||
		MPLog(@"postDataString - %@", parameterString);
 | 
			
		||||
		
 | 
			
		||||
		[aRequest setURL:url];
 | 
			
		||||
		[aRequest setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"];
 | 
			
		||||
		[aRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 | 
			
		||||
		[aRequest setHTTPBody:postData];
 | 
			
		||||
	} else {
 | 
			
		||||
		[NSException raise:@"UnhandledHTTPMethodException" format:@"The requested HTTP method, %@, is not supported", HTTPMethod];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[parameterString release];
 | 
			
		||||
	[signatureParameter release];		
 | 
			
		||||
	
 | 
			
		||||
	urlRequest = [aRequest retain];
 | 
			
		||||
	[aRequest release];
 | 
			
		||||
		
 | 
			
		||||
	return aRequest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (void)addParameters:(NSArray *)inParameters {
 | 
			
		||||
	[parameters addObjectsFromArray:inParameters];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthURLResponse.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface MPOAuthURLResponse : NSObject {
 | 
			
		||||
	NSURLResponse	*urlResponse;
 | 
			
		||||
	NSDictionary	*oauthParameters;
 | 
			
		||||
}
 | 
			
		||||
- (void)setResponse:(NSURLResponse *)theResponse;
 | 
			
		||||
- (NSURLResponse *)response;
 | 
			
		||||
 | 
			
		||||
- (void)setOauthParameters:(NSDictionary *)theParameters;
 | 
			
		||||
- (NSDictionary *)oauthParameters;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPOAuthURLResponse.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPOAuthURLResponse.h"
 | 
			
		||||
 | 
			
		||||
@implementation MPOAuthURLResponse
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
	[urlResponse release];
 | 
			
		||||
	[oauthParameters release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setResponse:(NSURLResponse *)theResponse {
 | 
			
		||||
	[urlResponse release];
 | 
			
		||||
	urlResponse = [theResponse retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSURLResponse *)response {
 | 
			
		||||
	return urlResponse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setOauthParameters:(NSDictionary *)theParameters {
 | 
			
		||||
	[oauthParameters release];
 | 
			
		||||
	oauthParameters = [theParameters retain];
 | 
			
		||||
}
 | 
			
		||||
- (NSDictionary *)oauthParameters {
 | 
			
		||||
	return oauthParameters;
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
@ -1,31 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPURLParameter.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface MPURLRequestParameter : NSObject {
 | 
			
		||||
	NSString *name;
 | 
			
		||||
	NSString *value;
 | 
			
		||||
}
 | 
			
		||||
- (void)setName:(NSString *)theName;
 | 
			
		||||
- (NSString *)name;
 | 
			
		||||
- (void)setValue:(NSString *)theValue;
 | 
			
		||||
- (NSString *)value;
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)parametersFromString:(NSString *)inString;
 | 
			
		||||
+ (NSArray *)parametersFromDictionary:(NSDictionary *)inDictionary;
 | 
			
		||||
+ (NSDictionary *)parameterDictionaryFromString:(NSString *)inString;
 | 
			
		||||
+ (NSString *)parameterStringForParameters:(NSArray *)inParameters;
 | 
			
		||||
+ (NSString *)parameterStringForDictionary:(NSDictionary *)inParameterDictionary;
 | 
			
		||||
 | 
			
		||||
- (id)initWithName:(NSString *)inName andValue:(NSString *)inValue;
 | 
			
		||||
 | 
			
		||||
- (NSString *)URLEncodedParameterString;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,170 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MPURLParameter.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
@implementation MPURLRequestParameter
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)parametersFromString:(NSString *)inString {
 | 
			
		||||
	NSMutableArray *foundParameters = [NSMutableArray arrayWithCapacity:10];
 | 
			
		||||
	NSScanner *parameterScanner = [[NSScanner alloc] initWithString:inString];
 | 
			
		||||
	NSString *thisName = nil;
 | 
			
		||||
	NSString *thisValue = nil;
 | 
			
		||||
	MPURLRequestParameter *currentParameter = nil;
 | 
			
		||||
	
 | 
			
		||||
	while (![parameterScanner isAtEnd]) {
 | 
			
		||||
		thisName = nil;
 | 
			
		||||
		thisValue = nil;
 | 
			
		||||
		
 | 
			
		||||
		[parameterScanner scanUpToString:@"=" intoString:&thisName];
 | 
			
		||||
		[parameterScanner scanString:@"=" intoString:NULL];
 | 
			
		||||
		[parameterScanner scanUpToString:@"&" intoString:&thisValue];
 | 
			
		||||
		[parameterScanner scanString:@"&" intoString:NULL];		
 | 
			
		||||
		
 | 
			
		||||
		currentParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
		currentParameter.name = thisName;
 | 
			
		||||
		currentParameter.value = [thisValue stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 | 
			
		||||
		
 | 
			
		||||
		[foundParameters addObject:currentParameter];
 | 
			
		||||
		
 | 
			
		||||
		[currentParameter release];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[parameterScanner release];
 | 
			
		||||
	
 | 
			
		||||
	return foundParameters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSArray *)parametersFromDictionary:(NSDictionary *)inDictionary {
 | 
			
		||||
	NSMutableArray *parameterArray = [[NSMutableArray alloc] init];
 | 
			
		||||
	MPURLRequestParameter *aURLParameter = nil;
 | 
			
		||||
	
 | 
			
		||||
	NSArray *keys = [inDictionary allKeys];
 | 
			
		||||
	for (int i=0; i<[keys count]; i++) {
 | 
			
		||||
		aURLParameter = [[MPURLRequestParameter alloc] init];
 | 
			
		||||
		aURLParameter.name = [keys objectAtIndex:i];
 | 
			
		||||
		aURLParameter.value = [inDictionary objectForKey:[keys objectAtIndex:i]];
 | 
			
		||||
		
 | 
			
		||||
		[parameterArray addObject:aURLParameter];
 | 
			
		||||
		[aURLParameter release];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return [parameterArray autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSDictionary *)parameterDictionaryFromString:(NSString *)inString {
 | 
			
		||||
	NSMutableDictionary *foundParameters = [NSMutableDictionary dictionaryWithCapacity:10];
 | 
			
		||||
	if (inString) {
 | 
			
		||||
		NSScanner *parameterScanner = [[NSScanner alloc] initWithString:inString];
 | 
			
		||||
		NSString *thisName = nil;
 | 
			
		||||
		NSString *thisValue = nil;
 | 
			
		||||
		
 | 
			
		||||
		while (![parameterScanner isAtEnd]) {
 | 
			
		||||
			thisName = nil;
 | 
			
		||||
			thisValue = nil;
 | 
			
		||||
			
 | 
			
		||||
			[parameterScanner scanUpToString:@"=" intoString:&thisName];
 | 
			
		||||
			[parameterScanner scanString:@"=" intoString:NULL];
 | 
			
		||||
			[parameterScanner scanUpToString:@"&" intoString:&thisValue];
 | 
			
		||||
			[parameterScanner scanString:@"&" intoString:NULL];		
 | 
			
		||||
			
 | 
			
		||||
			[foundParameters setObject:[thisValue stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:thisName];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		[parameterScanner release];
 | 
			
		||||
	}
 | 
			
		||||
	return foundParameters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)parameterStringForParameters:(NSArray *)inParameters {
 | 
			
		||||
	NSMutableString *queryString = [[NSMutableString alloc] init];
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	int parameterCount = [inParameters count];	
 | 
			
		||||
	MPURLRequestParameter *aParameter = nil;
 | 
			
		||||
	
 | 
			
		||||
	for (; i < parameterCount; i++) {
 | 
			
		||||
		aParameter = [inParameters objectAtIndex:i];
 | 
			
		||||
		[queryString appendString:[aParameter URLEncodedParameterString]];
 | 
			
		||||
		
 | 
			
		||||
		if (i < parameterCount - 1) {
 | 
			
		||||
			[queryString appendString:@"&"];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return [queryString autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+ (NSString *)parameterStringForDictionary:(NSDictionary *)inParameterDictionary {
 | 
			
		||||
	NSArray *parameters = [self parametersFromDictionary:inParameterDictionary];
 | 
			
		||||
	NSString *queryString = [self parameterStringForParameters:parameters];
 | 
			
		||||
	
 | 
			
		||||
	return queryString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (id)init {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (id)initWithName:(NSString *)inName andValue:(NSString *)inValue {
 | 
			
		||||
	if ((self = [super init])) {
 | 
			
		||||
		name = [inName copy];
 | 
			
		||||
		value = [inValue copy];
 | 
			
		||||
	}
 | 
			
		||||
	return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (oneway void)dealloc {
 | 
			
		||||
	[name release];
 | 
			
		||||
	[value release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)setName:(NSString *)theName {
 | 
			
		||||
	[name release];
 | 
			
		||||
	name = [theName copy];
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)name {
 | 
			
		||||
	return name;
 | 
			
		||||
}
 | 
			
		||||
- (void)setValue:(NSString *)theValue {
 | 
			
		||||
	[value release];
 | 
			
		||||
	value = [theValue copy];
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)value {
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSString *)URLEncodedParameterString {
 | 
			
		||||
	return [NSString stringWithFormat:@"%@=%@", [name stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding], value ? [value stringByAddingURIPercentEscapesUsingEncoding:NSUTF8StringEncoding] : @""];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma mark -
 | 
			
		||||
 | 
			
		||||
- (NSComparisonResult)compare:(id)inObject {
 | 
			
		||||
	NSComparisonResult result = [name compare:[(MPURLRequestParameter *)inObject name]];
 | 
			
		||||
	
 | 
			
		||||
	if (result == NSOrderedSame) {
 | 
			
		||||
		result = [value compare:[(MPURLRequestParameter *)inObject value]];
 | 
			
		||||
	}
 | 
			
		||||
								 
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)description {
 | 
			
		||||
	return [NSString stringWithFormat:@"<%@: %p %@>", NSStringFromClass([self class]), self, [self URLEncodedParameterString]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSString+URLEscapingAdditions.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.07.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface NSString (MPURLEscapingAdditions)
 | 
			
		||||
 | 
			
		||||
- (BOOL)isIPAddress;
 | 
			
		||||
- (NSString *)stringByAddingURIPercentEscapesUsingEncoding:(NSStringEncoding)inEncoding;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface NSURL (MPURLEscapingAdditions)
 | 
			
		||||
- (NSString *)stringByAddingURIPercentEscapesUsingEncoding:(NSStringEncoding)inEncoding;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSString+URLEscapingAdditions.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.07.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation NSString (MPURLEscapingAdditions)
 | 
			
		||||
 | 
			
		||||
- (BOOL)isIPAddress {
 | 
			
		||||
	BOOL isIPAddress = NO;
 | 
			
		||||
	NSArray *components = [self componentsSeparatedByString:@"."];
 | 
			
		||||
	NSCharacterSet *invalidCharacters = [[NSCharacterSet characterSetWithCharactersInString:@"1234567890"] invertedSet]; 
 | 
			
		||||
 | 
			
		||||
	if ([components count] == 4) {
 | 
			
		||||
		NSString *part1 = [components objectAtIndex:0];
 | 
			
		||||
		NSString *part2 = [components objectAtIndex:1];
 | 
			
		||||
		NSString *part3 = [components objectAtIndex:2];
 | 
			
		||||
		NSString *part4 = [components objectAtIndex:3];
 | 
			
		||||
 | 
			
		||||
		if ([part1 rangeOfCharacterFromSet:invalidCharacters].location == NSNotFound &&
 | 
			
		||||
			[part2 rangeOfCharacterFromSet:invalidCharacters].location == NSNotFound &&
 | 
			
		||||
			[part3 rangeOfCharacterFromSet:invalidCharacters].location == NSNotFound &&
 | 
			
		||||
			[part4 rangeOfCharacterFromSet:invalidCharacters].location == NSNotFound ) {
 | 
			
		||||
 | 
			
		||||
			if ([part1 intValue] < 255 &&
 | 
			
		||||
				[part2 intValue] < 255 &&
 | 
			
		||||
				[part3 intValue] < 255 &&
 | 
			
		||||
				[part4 intValue] < 255) {
 | 
			
		||||
				isIPAddress = YES;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return isIPAddress;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringByAddingURIPercentEscapesUsingEncoding:(NSStringEncoding)inEncoding {
 | 
			
		||||
	NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
 | 
			
		||||
																				  (CFStringRef)self,
 | 
			
		||||
																				  NULL,
 | 
			
		||||
																				  (CFStringRef)@":/?=,!$&'()*+;[]@#",
 | 
			
		||||
																				  CFStringConvertNSStringEncodingToEncoding(inEncoding));
 | 
			
		||||
	
 | 
			
		||||
	return [escapedString autorelease];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@implementation NSURL (MPURLEscapingAdditions)
 | 
			
		||||
 | 
			
		||||
- (NSString *)stringByAddingURIPercentEscapesUsingEncoding:(NSStringEncoding)inEncoding {
 | 
			
		||||
	return [[self absoluteString] stringByAddingURIPercentEscapesUsingEncoding:inEncoding];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSURL+MPURLParameterAdditions.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.08.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface NSURL (MPURLParameterAdditions)
 | 
			
		||||
 | 
			
		||||
- (NSURL *)urlByAddingParameters:(NSArray *)inParameters;
 | 
			
		||||
- (NSURL *)urlByAddingParameterDictionary:(NSDictionary *)inParameters;
 | 
			
		||||
- (NSURL *)urlByRemovingQuery;
 | 
			
		||||
- (NSString *)absoluteNormalizedString;
 | 
			
		||||
 | 
			
		||||
- (BOOL)domainMatches:(NSString *)inString;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,98 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSURL+MPURLParameterAdditions.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.08.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "NSURL+MPURLParameterAdditions.h"
 | 
			
		||||
#import "MPURLRequestParameter.h"
 | 
			
		||||
#import "NSString+URLEscapingAdditions.h"
 | 
			
		||||
 | 
			
		||||
@implementation NSURL (MPURLParameterAdditions)
 | 
			
		||||
 | 
			
		||||
- (NSURL *)urlByAddingParameters:(NSArray *)inParameters {
 | 
			
		||||
	NSMutableArray *parameters = [[NSMutableArray alloc] init];
 | 
			
		||||
	NSString *queryString = [self query];
 | 
			
		||||
	NSString *absoluteString = [self absoluteString];
 | 
			
		||||
	NSRange parameterRange = [absoluteString rangeOfString:@"?"];
 | 
			
		||||
	
 | 
			
		||||
	if (parameterRange.location != NSNotFound) {
 | 
			
		||||
		parameterRange.length = [absoluteString length] - parameterRange.location;
 | 
			
		||||
		[parameters addObjectsFromArray:[MPURLRequestParameter parametersFromString:queryString]];
 | 
			
		||||
		absoluteString = [absoluteString substringToIndex:parameterRange.location];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[parameters addObjectsFromArray:inParameters];
 | 
			
		||||
	
 | 
			
		||||
	return [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", absoluteString, [MPURLRequestParameter parameterStringForParameters:[parameters autorelease]]]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSURL *)urlByAddingParameterDictionary:(NSDictionary *)inParameterDictionary {
 | 
			
		||||
	NSMutableDictionary *parameterDictionary = [inParameterDictionary mutableCopy];
 | 
			
		||||
	NSString *queryString = [self query];
 | 
			
		||||
	NSString *absoluteString = [self absoluteString];
 | 
			
		||||
	NSRange parameterRange = [absoluteString rangeOfString:@"?"];
 | 
			
		||||
	NSURL *composedURL = self;
 | 
			
		||||
	
 | 
			
		||||
	if (parameterRange.location != NSNotFound) {
 | 
			
		||||
		parameterRange.length = [absoluteString length] - parameterRange.location;
 | 
			
		||||
		
 | 
			
		||||
		//[parameterDictionary addEntriesFromDictionary:inParameterDictionary];
 | 
			
		||||
		[parameterDictionary addEntriesFromDictionary:[MPURLRequestParameter parameterDictionaryFromString:queryString]];
 | 
			
		||||
		
 | 
			
		||||
		composedURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", [absoluteString substringToIndex:parameterRange.location], [MPURLRequestParameter parameterStringForDictionary:parameterDictionary]]];
 | 
			
		||||
	} else if ([parameterDictionary count]) {
 | 
			
		||||
		composedURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", absoluteString, [MPURLRequestParameter parameterStringForDictionary:parameterDictionary]]];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	[parameterDictionary release];
 | 
			
		||||
 | 
			
		||||
	return composedURL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSURL *)urlByRemovingQuery {
 | 
			
		||||
	NSURL *composedURL = self;
 | 
			
		||||
	NSString *absoluteString = [self absoluteString];
 | 
			
		||||
	NSRange queryRange = [absoluteString rangeOfString:@"?"];
 | 
			
		||||
	
 | 
			
		||||
	if (queryRange.location != NSNotFound) {
 | 
			
		||||
		NSString *urlSansQuery = [absoluteString substringToIndex:queryRange.location];
 | 
			
		||||
		composedURL = [NSURL URLWithString:urlSansQuery];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return composedURL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSString *)absoluteNormalizedString {
 | 
			
		||||
	NSString *normalizedString = [self absoluteString];
 | 
			
		||||
 | 
			
		||||
	if ([[self path] length] == 0 && [[self query] length] == 0) {
 | 
			
		||||
		normalizedString = [NSString stringWithFormat:@"%@/", [self absoluteString]];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return normalizedString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)domainMatches:(NSString *)inString {
 | 
			
		||||
	BOOL matches = NO;
 | 
			
		||||
	
 | 
			
		||||
	NSString *domain = [self host];
 | 
			
		||||
	matches = [domain isIPAddress] && [domain isEqualToString:inString];
 | 
			
		||||
	
 | 
			
		||||
	int domainLength = [domain length];
 | 
			
		||||
	int requestedDomainLength = [inString length];
 | 
			
		||||
	
 | 
			
		||||
	if (!matches) {
 | 
			
		||||
		if (domainLength > requestedDomainLength) {
 | 
			
		||||
			matches = [domain rangeOfString:inString].location == (domainLength - requestedDomainLength);
 | 
			
		||||
		} else if (domainLength == (requestedDomainLength - 1)) {
 | 
			
		||||
			matches = ([inString compare:domain options:NSCaseInsensitiveSearch range:NSMakeRange(1, domainLength)] == NSOrderedSame);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return matches;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSURL+MPEncodingAdditions.h
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Foundation/Foundation.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface NSURLResponse (EncodingAdditions)
 | 
			
		||||
- (NSStringEncoding)encoding;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSURL+MPEncodingAdditions.m
 | 
			
		||||
//  MPOAuthConnection
 | 
			
		||||
//
 | 
			
		||||
//  Created by Karl Adam on 08.12.05.
 | 
			
		||||
//  Copyright 2008 matrixPointer. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "NSURLResponse+Encoding.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation NSURLResponse (EncodingAdditions)
 | 
			
		||||
 | 
			
		||||
- (NSStringEncoding)encoding {
 | 
			
		||||
	NSStringEncoding encoding = NSUTF8StringEncoding;
 | 
			
		||||
	
 | 
			
		||||
	if ([self textEncodingName]) {
 | 
			
		||||
		CFStringEncoding cfStringEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)[self textEncodingName]);
 | 
			
		||||
		if (cfStringEncoding != kCFStringEncodingInvalidId) {
 | 
			
		||||
			encoding = CFStringConvertEncodingToNSStringEncoding(cfStringEncoding); 
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return encoding;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSString+Dropbox.h
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 7/19/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@interface NSString (Dropbox)
 | 
			
		||||
 | 
			
		||||
// This will take a path for a resource and normalize so you can compare paths
 | 
			
		||||
- (NSString*)normalizedDropboxPath;
 | 
			
		||||
 | 
			
		||||
// Normalizes both paths and compares them
 | 
			
		||||
- (BOOL)isEqualToDropboxPath:(NSString*)otherPath;
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  NSString+Dropbox.m
 | 
			
		||||
//  DropboxSDK
 | 
			
		||||
//
 | 
			
		||||
//  Created by Brian Smith on 7/19/10.
 | 
			
		||||
//  Copyright 2010 Dropbox, Inc. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "NSString+Dropbox.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation NSString (Dropbox)
 | 
			
		||||
 | 
			
		||||
- (NSString*)normalizedDropboxPath {
 | 
			
		||||
    if ([self isEqual:@"/"]) return @"";
 | 
			
		||||
    return [[self lowercaseString] precomposedStringWithCanonicalMapping];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isEqualToDropboxPath:(NSString*)otherPath {
 | 
			
		||||
    return [[self normalizedDropboxPath] isEqualToString:[otherPath normalizedDropboxPath]];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 9.2 KiB  | 
@ -1,39 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMDropboxPlugIn.h
 | 
			
		||||
//  CocoaShare
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 1/19/11.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import <Cocoa/Cocoa.h>
 | 
			
		||||
#import "DBRestClient.h"
 | 
			
		||||
#import "DBAccountInfo.h"
 | 
			
		||||
#import "DBMetadata.h"
 | 
			
		||||
 | 
			
		||||
@interface MGMDropboxPlugIn : NSObject <DBRestClientDelegate> {
 | 
			
		||||
	IBOutlet NSView *view;
 | 
			
		||||
	IBOutlet NSTextField *emailField;
 | 
			
		||||
	IBOutlet NSTextField *passwordField;
 | 
			
		||||
	IBOutlet NSButton *loginButton;
 | 
			
		||||
	
 | 
			
		||||
	IBOutlet NSOutlineView *publicOutline;
 | 
			
		||||
	BOOL loadingPublic;
 | 
			
		||||
	NSMutableArray *publicFolder;
 | 
			
		||||
	
 | 
			
		||||
	BOOL userLoggingIn;
 | 
			
		||||
	BOOL loggedIn;
 | 
			
		||||
	DBSession *dropboxSession;
 | 
			
		||||
	DBRestClient *dropbox;
 | 
			
		||||
	DBAccountInfo *dropboxAccountInfo;
 | 
			
		||||
	
 | 
			
		||||
	NSString *filePath;
 | 
			
		||||
}
 | 
			
		||||
- (void)releaseView;
 | 
			
		||||
 | 
			
		||||
- (void)login;
 | 
			
		||||
- (void)lockLogin;
 | 
			
		||||
- (void)unlockLogin;
 | 
			
		||||
- (IBAction)login:(id)sender;
 | 
			
		||||
- (NSDictionary *)dataForPath:(NSString *)thePath inArray:(NSArray *)theArray;
 | 
			
		||||
@end
 | 
			
		||||
@ -1,250 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
//  MGMDropboxPlugIn.m
 | 
			
		||||
//  CocoaShare
 | 
			
		||||
//
 | 
			
		||||
//  Created by Mr. Gecko on 1/19/11.
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#import "MGMDropboxPlugIn.h"
 | 
			
		||||
#import "MGMController.h"
 | 
			
		||||
#import "MGMAddons.h"
 | 
			
		||||
 | 
			
		||||
NSString * const MGMCopyright = @"Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/";
 | 
			
		||||
 | 
			
		||||
NSString * const MGMDropboxEmail = @"MGMDropboxUser";
 | 
			
		||||
NSString * const MGMDropboxPath = @"MGMDropboxPath";
 | 
			
		||||
#warning Add and remove the keys when publishing source code.
 | 
			
		||||
NSString * const MGMDropboxKey = @"";
 | 
			
		||||
NSString * const MGMDropboxSecret = @"";
 | 
			
		||||
 | 
			
		||||
NSString * const MGMDropboxPublic = @"/Public";
 | 
			
		||||
NSString * const MGMDropboxFPath = @"path";
 | 
			
		||||
NSString * const MGMDropboxFContents = @"contents";
 | 
			
		||||
 | 
			
		||||
@implementation MGMDropboxPlugIn
 | 
			
		||||
- (void)dealloc {
 | 
			
		||||
	[self releaseView];
 | 
			
		||||
	[publicFolder release];
 | 
			
		||||
	[dropboxSession release];
 | 
			
		||||
	[dropbox release];
 | 
			
		||||
	[dropboxAccountInfo release];
 | 
			
		||||
	[filePath release];
 | 
			
		||||
	[super dealloc];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)isAccountPlugIn {
 | 
			
		||||
	return YES;
 | 
			
		||||
}
 | 
			
		||||
- (NSString *)plugInName {
 | 
			
		||||
	return @"Dropbox";
 | 
			
		||||
}
 | 
			
		||||
- (NSView *)plugInView {
 | 
			
		||||
	if (view==nil) {
 | 
			
		||||
		if (![NSBundle loadNibNamed:@"DropboxAccountPane" owner:self]) {
 | 
			
		||||
			NSLog(@"Unable to load Dropbox Account Pane");
 | 
			
		||||
		} else {
 | 
			
		||||
			NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
			NSString *user = [defaults objectForKey:MGMDropboxEmail];
 | 
			
		||||
			if (user!=nil)
 | 
			
		||||
				[emailField setStringValue:user];
 | 
			
		||||
			NSString *password = [[MGMController sharedController] password];
 | 
			
		||||
			if (password!=nil)
 | 
			
		||||
				[passwordField setStringValue:password];
 | 
			
		||||
			if (loggedIn) {
 | 
			
		||||
				loadingPublic = YES;
 | 
			
		||||
				[dropbox loadMetadata:MGMDropboxPublic];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return view;
 | 
			
		||||
}
 | 
			
		||||
- (void)releaseView {
 | 
			
		||||
	[view release];
 | 
			
		||||
	view = nil;
 | 
			
		||||
	emailField = nil;
 | 
			
		||||
	passwordField = nil;
 | 
			
		||||
	loginButton = nil;
 | 
			
		||||
	publicOutline = nil;
 | 
			
		||||
	[publicFolder release];
 | 
			
		||||
	publicFolder = nil;
 | 
			
		||||
}
 | 
			
		||||
- (void)setCurrentPlugIn:(BOOL)isCurrent {
 | 
			
		||||
	if (isCurrent) {
 | 
			
		||||
		dropboxSession = [[DBSession alloc] initWithConsumerKey:MGMDropboxKey consumerSecret:MGMDropboxSecret];
 | 
			
		||||
		[DBSession setSharedSession:dropboxSession];
 | 
			
		||||
		dropbox = [[DBRestClient alloc] initWithSession:dropboxSession];
 | 
			
		||||
		[dropbox setDelegate:self];
 | 
			
		||||
		userLoggingIn = NO;
 | 
			
		||||
		[self login];
 | 
			
		||||
	} else {
 | 
			
		||||
		[dropboxSession release];
 | 
			
		||||
		dropboxSession = nil;
 | 
			
		||||
		[dropbox release];
 | 
			
		||||
		dropbox = nil;
 | 
			
		||||
		[dropboxAccountInfo release];
 | 
			
		||||
		dropboxAccountInfo = nil;
 | 
			
		||||
		loggedIn = NO;
 | 
			
		||||
		NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
		[defaults removeObjectForKey:MGMDropboxEmail];
 | 
			
		||||
		[defaults removeObjectForKey:MGMDropboxPath];
 | 
			
		||||
		[dropboxSession updateAccessToken:nil accessTokenSecret:nil];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)login {
 | 
			
		||||
	NSString *user = [[NSUserDefaults standardUserDefaults] objectForKey:MGMDropboxEmail];
 | 
			
		||||
	NSString *password = [[MGMController sharedController] password];
 | 
			
		||||
	if (user!=nil)
 | 
			
		||||
		[dropbox loginWithEmail:user password:password];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)lockLogin {
 | 
			
		||||
	[emailField setEnabled:NO];
 | 
			
		||||
	[passwordField setEnabled:NO];
 | 
			
		||||
	[loginButton setEnabled:NO];
 | 
			
		||||
	[loginButton setTitle:[@"Logging In" localizedFor:self]];
 | 
			
		||||
}
 | 
			
		||||
- (void)unlockLogin {
 | 
			
		||||
	[emailField setEnabled:YES];
 | 
			
		||||
	[passwordField setEnabled:YES];
 | 
			
		||||
	[loginButton setEnabled:YES];
 | 
			
		||||
	[loginButton setTitle:[@"Login" localizedFor:self]];
 | 
			
		||||
}
 | 
			
		||||
- (IBAction)login:(id)sender {
 | 
			
		||||
	if ([[emailField stringValue] isEqual:@""]) {
 | 
			
		||||
		NSAlert *alert = [[NSAlert new] autorelease];
 | 
			
		||||
		[alert setMessageText:[@"Email Required" localizedFor:self]];
 | 
			
		||||
		[alert setInformativeText:[@"Please enter your email." localizedFor:self]];
 | 
			
		||||
		[alert runModal];
 | 
			
		||||
    } else if ([[passwordField stringValue] isEqual:@""]) {
 | 
			
		||||
		NSAlert *alert = [[NSAlert new] autorelease];
 | 
			
		||||
		[alert setMessageText:[@"Password Required" localizedFor:self]];
 | 
			
		||||
		[alert setInformativeText:[@"Please enter your password." localizedFor:self]];
 | 
			
		||||
		[alert runModal];
 | 
			
		||||
    } else {
 | 
			
		||||
		userLoggingIn = YES;
 | 
			
		||||
		[[MGMController sharedController] setPassword:[passwordField stringValue]];
 | 
			
		||||
		[[NSUserDefaults standardUserDefaults] setObject:[emailField stringValue] forKey:MGMDropboxEmail];
 | 
			
		||||
		[self lockLogin];
 | 
			
		||||
		[self login];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient *)client loginFailedWithError:(NSError *)error {
 | 
			
		||||
	NSLog(@"Dropbox Error: %@", error);
 | 
			
		||||
	NSAlert *alert = [[NSAlert new] autorelease];
 | 
			
		||||
	[alert setMessageText:[@"Account Error" localizedFor:self]];
 | 
			
		||||
	[alert setInformativeText:[error localizedDescription]];
 | 
			
		||||
	[alert runModal];
 | 
			
		||||
	[self unlockLogin];
 | 
			
		||||
}
 | 
			
		||||
- (void)restClientDidLogin:(DBRestClient *)client {
 | 
			
		||||
	NSLog(@"Dropbox: Logged in.");
 | 
			
		||||
	loggedIn = YES;
 | 
			
		||||
	[dropbox loadAccountInfo];
 | 
			
		||||
	if (userLoggingIn) {
 | 
			
		||||
		loadingPublic = YES;
 | 
			
		||||
		[dropbox loadMetadata:MGMDropboxPublic];
 | 
			
		||||
		NSAlert *alert = [[NSAlert new] autorelease];
 | 
			
		||||
		[alert setMessageText:[@"Login Successful" localizedFor:self]];
 | 
			
		||||
		[alert setInformativeText:[@"You have successfully logged into your account." localizedFor:self]];
 | 
			
		||||
		[alert runModal];
 | 
			
		||||
		[self unlockLogin];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (NSDictionary *)dataForPath:(NSString *)thePath inArray:(NSArray *)theArray {
 | 
			
		||||
	for (unsigned long i=0; i<[theArray count]; i++) {
 | 
			
		||||
		NSDictionary *thisData = [theArray objectAtIndex:i];
 | 
			
		||||
		if ([[thisData objectForKey:MGMDropboxFPath] isEqual:thePath])
 | 
			
		||||
			return thisData;
 | 
			
		||||
		NSDictionary *data = [self dataForPath:thePath inArray:[thisData objectForKey:MGMDropboxFContents]];
 | 
			
		||||
		if (data!=nil)
 | 
			
		||||
			return data;
 | 
			
		||||
	}
 | 
			
		||||
	return nil;
 | 
			
		||||
}
 | 
			
		||||
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
 | 
			
		||||
	NSMutableArray *currentArray = nil;
 | 
			
		||||
	if ([[metadata path] isEqual:MGMDropboxPublic]) {
 | 
			
		||||
		loadingPublic = NO;
 | 
			
		||||
		[publicFolder release];
 | 
			
		||||
		publicFolder = [NSMutableArray new];
 | 
			
		||||
		currentArray = publicFolder;
 | 
			
		||||
	} else {
 | 
			
		||||
		currentArray = [[self dataForPath:[metadata path] inArray:publicFolder] objectForKey:MGMDropboxFContents];
 | 
			
		||||
	}
 | 
			
		||||
	NSArray *metadataContents = [metadata contents];
 | 
			
		||||
	for (unsigned long i=0; i<[metadataContents count]; i++) {
 | 
			
		||||
		if ([[metadataContents objectAtIndex:i] isDirectory]) {
 | 
			
		||||
			DBMetadata *thisMetadata = [metadataContents objectAtIndex:i];
 | 
			
		||||
			[dropbox loadMetadata:[thisMetadata path]];
 | 
			
		||||
			[currentArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:[thisMetadata path], MGMDropboxFPath, [NSMutableArray array], MGMDropboxFContents, nil]];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	[publicOutline reloadData];
 | 
			
		||||
}
 | 
			
		||||
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(NSDictionary *)item {
 | 
			
		||||
	return (item==nil ? [publicFolder count] : [[item objectForKey:MGMDropboxFContents] count]);
 | 
			
		||||
}
 | 
			
		||||
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(NSDictionary *)item {
 | 
			
		||||
	if ([[tableColumn identifier] isEqual:@"name"]) {
 | 
			
		||||
		return [[item objectForKey:MGMDropboxFPath] lastPathComponent];
 | 
			
		||||
	} else if ([[tableColumn identifier] isEqual:@"selected"]) {
 | 
			
		||||
		return [NSNumber numberWithBool:([[item objectForKey:MGMDropboxFPath] isEqual:[[NSUserDefaults standardUserDefaults] objectForKey:MGMDropboxPath]])];
 | 
			
		||||
	}
 | 
			
		||||
	return @"";
 | 
			
		||||
}
 | 
			
		||||
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(NSDictionary *)item {
 | 
			
		||||
	return (item==nil ? ([publicFolder count]>0) : ([[item objectForKey:MGMDropboxFContents] count]>0));
 | 
			
		||||
}
 | 
			
		||||
- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(NSDictionary *)item {
 | 
			
		||||
	return (item==nil ? [publicFolder objectAtIndex:index] : [[item objectForKey:MGMDropboxFContents] objectAtIndex:index]);
 | 
			
		||||
}
 | 
			
		||||
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(NSDictionary *)item {
 | 
			
		||||
	if ([object boolValue])
 | 
			
		||||
		[[NSUserDefaults standardUserDefaults] setObject:[item objectForKey:MGMDropboxFPath] forKey:MGMDropboxPath];
 | 
			
		||||
	else
 | 
			
		||||
		[[NSUserDefaults standardUserDefaults] removeObjectForKey:MGMDropboxPath];
 | 
			
		||||
	[publicOutline reloadData];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)restClient:(DBRestClient *)client loadedAccountInfo:(DBAccountInfo *)info {
 | 
			
		||||
	[dropboxAccountInfo release];
 | 
			
		||||
	dropboxAccountInfo = [info retain];
 | 
			
		||||
}
 | 
			
		||||
- (void)restClient:(DBRestClient *)client loadAccountInfoFailedWithError:(NSError *)error {
 | 
			
		||||
	NSAlert *alert = [[NSAlert new] autorelease];
 | 
			
		||||
	[alert setMessageText:[@"Account Error" localizedFor:self]];
 | 
			
		||||
	[alert setInformativeText:[@"Unable to get your account ID." localizedFor:self]];
 | 
			
		||||
	[alert runModal];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)sendFileAtPath:(NSString *)thePath withName:(NSString *)theName {
 | 
			
		||||
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
	if ([defaults objectForKey:MGMDropboxEmail]==nil) {
 | 
			
		||||
		NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:5 userInfo:[NSDictionary dictionaryWithObject:[@"Account is not logged in." localizedFor:self] forKey:NSLocalizedDescriptionKey]];
 | 
			
		||||
		[[MGMController sharedController] upload:thePath receivedError:error];
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	NSString *path = [[NSUserDefaults standardUserDefaults] objectForKey:MGMDropboxPath];
 | 
			
		||||
	if (path==nil) path = MGMDropboxPublic;
 | 
			
		||||
	filePath = [thePath retain];
 | 
			
		||||
	[dropbox uploadFile:theName toPath:path fromPath:thePath];
 | 
			
		||||
}
 | 
			
		||||
- (void)restClient:(DBRestClient *)client uploadedFile:(NSString *)destPath from:(NSString *)srcPath {
 | 
			
		||||
	NSString *finishPath = [[filePath retain] autorelease];
 | 
			
		||||
	[filePath release];
 | 
			
		||||
	filePath = nil;
 | 
			
		||||
	NSString *url = [NSString stringWithFormat:@"http://dl.dropbox.com/u/%@%@", [dropboxAccountInfo userId], [[destPath replace:MGMDropboxPublic with:@""] addPercentEscapes]];
 | 
			
		||||
	[[MGMController sharedController] uploadFinished:finishPath url:[NSURL URLWithString:url]];
 | 
			
		||||
}
 | 
			
		||||
- (void)restClient:(DBRestClient *)client uploadFileFailedWithError:(NSError *)error {
 | 
			
		||||
	NSString *finishPath = [[filePath retain] autorelease];
 | 
			
		||||
	[filePath release];
 | 
			
		||||
	filePath = nil;
 | 
			
		||||
	[[MGMController sharedController] upload:finishPath receivedError:error];
 | 
			
		||||
}
 | 
			
		||||
@end
 | 
			
		||||
@ -1,7 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
// Prefix header for all source files of the 'CocoaShare' target in the 'CocoaShare' project
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifdef __OBJC__
 | 
			
		||||
    #import <Cocoa/Cocoa.h>
 | 
			
		||||
#endif
 | 
			
		||||
@ -16,6 +16,8 @@
 | 
			
		||||
	IBOutlet NSButton *loginButton;
 | 
			
		||||
	BOOL userLoggingIn;
 | 
			
		||||
	int loginTries;
 | 
			
		||||
    
 | 
			
		||||
    BOOL isJSON;
 | 
			
		||||
}
 | 
			
		||||
- (void)releaseView;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -107,8 +107,14 @@ const BOOL MGMHTTPResponseInvisible = YES;
 | 
			
		||||
	[self unlockLogin];
 | 
			
		||||
}
 | 
			
		||||
- (void)checkDidFinish:(MGMURLBasicHandler *)theHandler {
 | 
			
		||||
    isJSON = [[[theHandler response] MIMEType] isEqual:@"application/json"];
 | 
			
		||||
	NSString *error = nil;
 | 
			
		||||
	NSDictionary *response = [NSPropertyListSerialization propertyListFromData:[theHandler data] mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&error];
 | 
			
		||||
    NSDictionary *response = nil;
 | 
			
		||||
    if (isJSON) {
 | 
			
		||||
        response = [[theHandler string] parseJSON];
 | 
			
		||||
    } else {
 | 
			
		||||
        response = [NSPropertyListSerialization propertyListFromData:[theHandler data] mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&error];
 | 
			
		||||
    }
 | 
			
		||||
	if (error!=nil)
 | 
			
		||||
		NSLog(@"HTTP Error: %@", error);
 | 
			
		||||
	if (response!=nil) {
 | 
			
		||||
@ -209,7 +215,12 @@ const BOOL MGMHTTPResponseInvisible = YES;
 | 
			
		||||
}
 | 
			
		||||
- (void)uploadDidFinish:(MGMURLBasicHandler *)theHandler {
 | 
			
		||||
	NSString *error = nil;
 | 
			
		||||
	NSDictionary *response = [NSPropertyListSerialization propertyListFromData:[theHandler data] mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&error];
 | 
			
		||||
	NSDictionary *response = nil;
 | 
			
		||||
    if (isJSON) {
 | 
			
		||||
        response = [[theHandler string] parseJSON];
 | 
			
		||||
    } else {
 | 
			
		||||
        response = [NSPropertyListSerialization propertyListFromData:[theHandler data] mutabilityOption:NSPropertyListImmutable format:nil errorDescription:&error];
 | 
			
		||||
    }
 | 
			
		||||
	if (error!=nil)
 | 
			
		||||
		NSLog(@"HTTP Error: %@", error);
 | 
			
		||||
	if (response!=nil) {
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,6 @@
 | 
			
		||||
/* End PBXAggregateTarget section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXBuildFile section */
 | 
			
		||||
		2A044C4E12E7612500E0B624 /* Dropbox.bundle in PlugIns */ = {isa = PBXBuildFile; fileRef = 2A044C4012E760DD00E0B624 /* Dropbox.bundle */; };
 | 
			
		||||
		2A044CE712E768D500E0B624 /* MGMDropboxPlugIn.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A044C7212E7621B00E0B624 /* MGMDropboxPlugIn.m */; };
 | 
			
		||||
		2A044D8F12E92DA800E0B624 /* MGMUsers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AEAB3F112E2A57400552BAA /* MGMUsers.framework */; };
 | 
			
		||||
		2A0501D512F49A7B000F74EA /* MGMWebDav.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A0501C612F49A7B000F74EA /* MGMWebDav.m */; };
 | 
			
		||||
		2A0501D612F49A7B000F74EA /* MGMWebDavAddons.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A0501C812F49A7B000F74EA /* MGMWebDavAddons.m */; };
 | 
			
		||||
@ -40,44 +38,11 @@
 | 
			
		||||
		2A0504B912F4E65C000F74EA /* MGMTwitpicPostWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A0504B812F4E65C000F74EA /* MGMTwitpicPostWindow.m */; };
 | 
			
		||||
		2A0504F312F4F024000F74EA /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A0504F212F4F024000F74EA /* QuartzCore.framework */; };
 | 
			
		||||
		2A280C8512EB50FB00435C36 /* Growl Registration Ticket.growlRegDict in Resources */ = {isa = PBXBuildFile; fileRef = 2A280C8412EB50FB00435C36 /* Growl Registration Ticket.growlRegDict */; };
 | 
			
		||||
		2A280EBF12EB7A5E00435C36 /* DBAccountInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E6A12EB7A5D00435C36 /* DBAccountInfo.m */; };
 | 
			
		||||
		2A280EC112EB7A5E00435C36 /* DBError.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E6E12EB7A5D00435C36 /* DBError.m */; };
 | 
			
		||||
		2A280EC412EB7A5E00435C36 /* DBMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E7412EB7A5D00435C36 /* DBMetadata.m */; };
 | 
			
		||||
		2A280EC512EB7A5E00435C36 /* DBQuota.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E7612EB7A5D00435C36 /* DBQuota.m */; };
 | 
			
		||||
		2A280EC612EB7A5E00435C36 /* DBRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E7812EB7A5E00435C36 /* DBRequest.m */; };
 | 
			
		||||
		2A280EC712EB7A5E00435C36 /* DBRestClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E7A12EB7A5E00435C36 /* DBRestClient.m */; };
 | 
			
		||||
		2A280EC812EB7A5E00435C36 /* DBSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E7C12EB7A5E00435C36 /* DBSession.m */; };
 | 
			
		||||
		2A280EC912EB7A5E00435C36 /* NSObject+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8112EB7A5E00435C36 /* NSObject+SBJSON.m */; };
 | 
			
		||||
		2A280ECA12EB7A5E00435C36 /* NSString+SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8312EB7A5E00435C36 /* NSString+SBJSON.m */; };
 | 
			
		||||
		2A280ECB12EB7A5E00435C36 /* SBJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8512EB7A5E00435C36 /* SBJSON.m */; };
 | 
			
		||||
		2A280ECC12EB7A5E00435C36 /* SBJsonBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8712EB7A5E00435C36 /* SBJsonBase.m */; };
 | 
			
		||||
		2A280ECD12EB7A5E00435C36 /* SBJsonParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8912EB7A5E00435C36 /* SBJsonParser.m */; };
 | 
			
		||||
		2A280ECE12EB7A5E00435C36 /* SBJsonWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8B12EB7A5E00435C36 /* SBJsonWriter.m */; };
 | 
			
		||||
		2A280ECF12EB7A5E00435C36 /* Base64Transcoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E8E12EB7A5E00435C36 /* Base64Transcoder.c */; };
 | 
			
		||||
		2A280ED012EB7A5E00435C36 /* MPOAuthAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9312EB7A5E00435C36 /* MPOAuthAPI.m */; };
 | 
			
		||||
		2A280ED112EB7A5E00435C36 /* MPOAuthAPIRequestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9512EB7A5E00435C36 /* MPOAuthAPIRequestLoader.m */; };
 | 
			
		||||
		2A280ED212EB7A5E00435C36 /* MPOAuthAuthenticationMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9712EB7A5E00435C36 /* MPOAuthAuthenticationMethod.m */; };
 | 
			
		||||
		2A280ED312EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9912EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.m */; };
 | 
			
		||||
		2A280ED412EB7A5E00435C36 /* MPOAuthConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9B12EB7A5E00435C36 /* MPOAuthConnection.m */; };
 | 
			
		||||
		2A280ED512EB7A5E00435C36 /* MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9C12EB7A5E00435C36 /* MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m */; };
 | 
			
		||||
		2A280ED612EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280E9E12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m */; };
 | 
			
		||||
		2A280ED712EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EA012EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.m */; };
 | 
			
		||||
		2A280ED812EB7A5E00435C36 /* MPOAuthSignatureParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EA412EB7A5E00435C36 /* MPOAuthSignatureParameter.m */; };
 | 
			
		||||
		2A280ED912EB7A5E00435C36 /* MPOAuthURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EA612EB7A5E00435C36 /* MPOAuthURLRequest.m */; };
 | 
			
		||||
		2A280EDA12EB7A5E00435C36 /* MPOAuthURLResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EA812EB7A5E00435C36 /* MPOAuthURLResponse.m */; };
 | 
			
		||||
		2A280EDB12EB7A5E00435C36 /* MPURLRequestParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EAA12EB7A5E00435C36 /* MPURLRequestParameter.m */; };
 | 
			
		||||
		2A280EDC12EB7A5E00435C36 /* NSString+URLEscapingAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EAC12EB7A5E00435C36 /* NSString+URLEscapingAdditions.m */; };
 | 
			
		||||
		2A280EDD12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EAE12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.m */; };
 | 
			
		||||
		2A280EDE12EB7A5E00435C36 /* NSURLResponse+Encoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EB012EB7A5E00435C36 /* NSURLResponse+Encoding.m */; };
 | 
			
		||||
		2A280EDF12EB7A5E00435C36 /* NSString+Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A280EB212EB7A5E00435C36 /* NSString+Dropbox.m */; };
 | 
			
		||||
		2A280EE912EB7A5E00435C36 /* db_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A280EBD12EB7A5E00435C36 /* db_logo.png */; };
 | 
			
		||||
		2A28110B12EBAC4B00435C36 /* MGMAddons.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A28110112EBABC400435C36 /* MGMAddons.m */; };
 | 
			
		||||
		2A28114F12EBCE4A00435C36 /* Account.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A28113D12EBCDFC00435C36 /* Account.png */; };
 | 
			
		||||
		2A28115012EBCE4A00435C36 /* AutoUpload.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A28113E12EBCDFC00435C36 /* AutoUpload.png */; };
 | 
			
		||||
		2A28115112EBCE4A00435C36 /* Events.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A28113F12EBCDFC00435C36 /* Events.png */; };
 | 
			
		||||
		2A28115212EBCE4A00435C36 /* General.png in Resources */ = {isa = PBXBuildFile; fileRef = 2A28114012EBCDFC00435C36 /* General.png */; };
 | 
			
		||||
		2A28148512ECD21900435C36 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A28148112ECD20C00435C36 /* Security.framework */; };
 | 
			
		||||
		2A28154412ECE26600435C36 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A28153D12ECE24300435C36 /* libcrypto.dylib */; };
 | 
			
		||||
		2A2F97A212F05C720069B37E /* FTP.bundle in PlugIns */ = {isa = PBXBuildFile; fileRef = 2A0C8C9412EF844F00A75AB7 /* FTP.bundle */; };
 | 
			
		||||
		2A2F995412F094F10069B37E /* SFTP.bundle in PlugIns */ = {isa = PBXBuildFile; fileRef = 2A2F994512F094710069B37E /* SFTP.bundle */; };
 | 
			
		||||
		2A2F996E12F095DA0069B37E /* MGMSFTPPlugIn.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A2F996D12F095DA0069B37E /* MGMSFTPPlugIn.m */; };
 | 
			
		||||
@ -89,7 +54,6 @@
 | 
			
		||||
		2A4FA5C912F9EDE0009F5B3A /* MGMLocalized.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A4FA5C812F9EDE0009F5B3A /* MGMLocalized.m */; };
 | 
			
		||||
		2A4FA61112F9F8DE009F5B3A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61012F9F8DE009F5B3A /* Localizable.strings */; };
 | 
			
		||||
		2A4FA61312F9F8E4009F5B3A /* HTTPAccountPane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61212F9F8E4009F5B3A /* HTTPAccountPane.xib */; };
 | 
			
		||||
		2A4FA61512F9F8E9009F5B3A /* DropboxAccountPane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61412F9F8E9009F5B3A /* DropboxAccountPane.xib */; };
 | 
			
		||||
		2A4FA61712F9F8F0009F5B3A /* FTPAccountPane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61612F9F8F0009F5B3A /* FTPAccountPane.xib */; };
 | 
			
		||||
		2A4FA61912F9F8F5009F5B3A /* SFTPAccountPane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61812F9F8F5009F5B3A /* SFTPAccountPane.xib */; };
 | 
			
		||||
		2A4FA61B12F9F8FA009F5B3A /* WebDavAccountPane.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A4FA61A12F9F8FA009F5B3A /* WebDavAccountPane.xib */; };
 | 
			
		||||
@ -140,13 +104,6 @@
 | 
			
		||||
/* End PBXBuildFile section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXContainerItemProxy section */
 | 
			
		||||
		2A044C4B12E7611E00E0B624 /* PBXContainerItemProxy */ = {
 | 
			
		||||
			isa = PBXContainerItemProxy;
 | 
			
		||||
			containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
 | 
			
		||||
			proxyType = 1;
 | 
			
		||||
			remoteGlobalIDString = 2A044C3F12E760DD00E0B624;
 | 
			
		||||
			remoteInfo = Dropbox;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501F912F49D54000F74EA /* PBXContainerItemProxy */ = {
 | 
			
		||||
			isa = PBXContainerItemProxy;
 | 
			
		||||
			containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
 | 
			
		||||
@ -213,7 +170,6 @@
 | 
			
		||||
			dstSubfolderSpec = 13;
 | 
			
		||||
			files = (
 | 
			
		||||
				2A48849B12E679DC001618B5 /* HTTP.bundle in PlugIns */,
 | 
			
		||||
				2A044C4E12E7612500E0B624 /* Dropbox.bundle in PlugIns */,
 | 
			
		||||
				2A2F97A212F05C720069B37E /* FTP.bundle in PlugIns */,
 | 
			
		||||
				2A2F995412F094F10069B37E /* SFTP.bundle in PlugIns */,
 | 
			
		||||
				2A5C1B4912F32EE3005153FA /* WebDav.bundle in PlugIns */,
 | 
			
		||||
@ -247,12 +203,6 @@
 | 
			
		||||
		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
 | 
			
		||||
		2A044B7912E68D3100E0B624 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/HTTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A044B8A12E68E9E00E0B624 /* MGMPlugInProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMPlugInProtocol.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A044C4012E760DD00E0B624 /* Dropbox.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Dropbox.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
			
		||||
		2A044C5B12E7614C00E0B624 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 | 
			
		||||
		2A044C6F12E761F300E0B624 /* prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prefix.pch; path = Classes/Dropbox/prefix.pch; sourceTree = "<group>"; };
 | 
			
		||||
		2A044C7112E7621B00E0B624 /* MGMDropboxPlugIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMDropboxPlugIn.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A044C7212E7621B00E0B624 /* MGMDropboxPlugIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMDropboxPlugIn.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A044C7812E762D100E0B624 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/DropboxAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A0501C512F49A7B000F74EA /* MGMWebDav.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMWebDav.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A0501C612F49A7B000F74EA /* MGMWebDav.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMWebDav.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A0501C712F49A7B000F74EA /* MGMWebDavAddons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMWebDavAddons.h; sourceTree = "<group>"; };
 | 
			
		||||
@ -298,7 +248,6 @@
 | 
			
		||||
		2A1E47AE1309636800102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/AutoUploadPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47AF1309653300102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/EventsPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B01309664400102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/HTTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B1130966CC00102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/DropboxAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B21309670A00102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/FTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B31309677800102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/SFTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B41309681300102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/WebDavAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
@ -306,72 +255,6 @@
 | 
			
		||||
		2A1E47B6130968F300102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/twitpicAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A1E47B71309695400102EBD /* sv */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = sv; path = sv.lproj/twitpicPostWindow.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A280C8412EB50FB00435C36 /* Growl Registration Ticket.growlRegDict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Growl Registration Ticket.growlRegDict"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E6912EB7A5D00435C36 /* DBAccountInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBAccountInfo.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E6A12EB7A5D00435C36 /* DBAccountInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBAccountInfo.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E6D12EB7A5D00435C36 /* DBError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBError.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E6E12EB7A5D00435C36 /* DBError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBError.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7312EB7A5D00435C36 /* DBMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBMetadata.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7412EB7A5D00435C36 /* DBMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBMetadata.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7512EB7A5D00435C36 /* DBQuota.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBQuota.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7612EB7A5D00435C36 /* DBQuota.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBQuota.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7712EB7A5E00435C36 /* DBRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBRequest.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7812EB7A5E00435C36 /* DBRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBRequest.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7912EB7A5E00435C36 /* DBRestClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBRestClient.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7A12EB7A5E00435C36 /* DBRestClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBRestClient.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7B12EB7A5E00435C36 /* DBSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBSession.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7C12EB7A5E00435C36 /* DBSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBSession.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7D12EB7A5E00435C36 /* DropboxSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DropboxSDK.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E7F12EB7A5E00435C36 /* JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8012EB7A5E00435C36 /* NSObject+SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+SBJSON.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8112EB7A5E00435C36 /* NSObject+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+SBJSON.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8212EB7A5E00435C36 /* NSString+SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SBJSON.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8312EB7A5E00435C36 /* NSString+SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SBJSON.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8412EB7A5E00435C36 /* SBJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJSON.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8512EB7A5E00435C36 /* SBJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJSON.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8612EB7A5E00435C36 /* SBJsonBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonBase.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8712EB7A5E00435C36 /* SBJsonBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonBase.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8812EB7A5E00435C36 /* SBJsonParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonParser.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8912EB7A5E00435C36 /* SBJsonParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonParser.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8A12EB7A5E00435C36 /* SBJsonWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SBJsonWriter.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8B12EB7A5E00435C36 /* SBJsonWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SBJsonWriter.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8E12EB7A5E00435C36 /* Base64Transcoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Base64Transcoder.c; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E8F12EB7A5E00435C36 /* Base64Transcoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64Transcoder.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9012EB7A5E00435C36 /* MPDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPDebug.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9112EB7A5E00435C36 /* MPOAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuth.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9212EB7A5E00435C36 /* MPOAuthAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthAPI.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9312EB7A5E00435C36 /* MPOAuthAPI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthAPI.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9412EB7A5E00435C36 /* MPOAuthAPIRequestLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthAPIRequestLoader.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9512EB7A5E00435C36 /* MPOAuthAPIRequestLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthAPIRequestLoader.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9612EB7A5E00435C36 /* MPOAuthAuthenticationMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthAuthenticationMethod.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9712EB7A5E00435C36 /* MPOAuthAuthenticationMethod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthAuthenticationMethod.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9812EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthAuthenticationMethodOAuth.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9912EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthAuthenticationMethodOAuth.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9A12EB7A5E00435C36 /* MPOAuthConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthConnection.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9B12EB7A5E00435C36 /* MPOAuthConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthConnection.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9C12EB7A5E00435C36 /* MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9D12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPOAuthCredentialConcreteStore+KeychainAdditions.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9E12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280E9F12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthCredentialConcreteStore.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA012EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthCredentialConcreteStore.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA112EB7A5E00435C36 /* MPOAuthCredentialStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthCredentialStore.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA212EB7A5E00435C36 /* MPOAuthParameterFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthParameterFactory.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA312EB7A5E00435C36 /* MPOAuthSignatureParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthSignatureParameter.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA412EB7A5E00435C36 /* MPOAuthSignatureParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthSignatureParameter.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA512EB7A5E00435C36 /* MPOAuthURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthURLRequest.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA612EB7A5E00435C36 /* MPOAuthURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthURLRequest.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA712EB7A5E00435C36 /* MPOAuthURLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOAuthURLResponse.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA812EB7A5E00435C36 /* MPOAuthURLResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOAuthURLResponse.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EA912EB7A5E00435C36 /* MPURLRequestParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPURLRequestParameter.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAA12EB7A5E00435C36 /* MPURLRequestParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPURLRequestParameter.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAB12EB7A5E00435C36 /* NSString+URLEscapingAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+URLEscapingAdditions.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAC12EB7A5E00435C36 /* NSString+URLEscapingAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+URLEscapingAdditions.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAD12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+MPURLParameterAdditions.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAE12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+MPURLParameterAdditions.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EAF12EB7A5E00435C36 /* NSURLResponse+Encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLResponse+Encoding.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EB012EB7A5E00435C36 /* NSURLResponse+Encoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLResponse+Encoding.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EB112EB7A5E00435C36 /* NSString+Dropbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Dropbox.h"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EB212EB7A5E00435C36 /* NSString+Dropbox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Dropbox.m"; sourceTree = "<group>"; };
 | 
			
		||||
		2A280EBD12EB7A5E00435C36 /* db_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = db_logo.png; sourceTree = "<group>"; };
 | 
			
		||||
		2A28110012EBABC400435C36 /* MGMAddons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMAddons.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A28110112EBABC400435C36 /* MGMAddons.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMAddons.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A28113D12EBCDFC00435C36 /* Account.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Account.png; sourceTree = "<group>"; };
 | 
			
		||||
@ -397,7 +280,6 @@
 | 
			
		||||
		2A48849412E678C3001618B5 /* MGMHTTPPlugIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGMHTTPPlugIn.h; sourceTree = "<group>"; };
 | 
			
		||||
		2A48849512E678C3001618B5 /* MGMHTTPPlugIn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGMHTTPPlugIn.m; sourceTree = "<group>"; };
 | 
			
		||||
		2A4C784112FC3A6300106ECD /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = pt_PT.lproj/HTTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A4C784312FC3A7400106ECD /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = pt_PT.lproj/DropboxAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A4C784512FC3A7C00106ECD /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = pt_PT.lproj/FTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A4C784712FC3A8300106ECD /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = pt_PT.lproj/SFTPAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
		2A4C784912FC3A8C00106ECD /* pt_PT */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = pt_PT; path = pt_PT.lproj/WebDavAccountPane.xib; sourceTree = "<group>"; };
 | 
			
		||||
@ -472,15 +354,6 @@
 | 
			
		||||
/* End PBXFileReference section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXFrameworksBuildPhase section */
 | 
			
		||||
		2A044C3E12E760DD00E0B624 /* Frameworks */ = {
 | 
			
		||||
			isa = PBXFrameworksBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				2A28154412ECE26600435C36 /* libcrypto.dylib in Frameworks */,
 | 
			
		||||
				2A28148512ECD21900435C36 /* Security.framework in Frameworks */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501EF12F49D08000F74EA /* Frameworks */ = {
 | 
			
		||||
			isa = PBXFrameworksBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
@ -581,7 +454,6 @@
 | 
			
		||||
			children = (
 | 
			
		||||
				8D1107320486CEB800E47090 /* CocoaShare.app */,
 | 
			
		||||
				2A48847612E6768D001618B5 /* HTTP.bundle */,
 | 
			
		||||
				2A044C4012E760DD00E0B624 /* Dropbox.bundle */,
 | 
			
		||||
				2A0C8C9412EF844F00A75AB7 /* FTP.bundle */,
 | 
			
		||||
				2A2F994512F094710069B37E /* SFTP.bundle */,
 | 
			
		||||
				2A5C1AF312F2FA6F005153FA /* WebDav.bundle */,
 | 
			
		||||
@ -609,7 +481,6 @@
 | 
			
		||||
			children = (
 | 
			
		||||
				2A48849112E67841001618B5 /* CocoaShare */,
 | 
			
		||||
				2A48849212E6785A001618B5 /* HTTP */,
 | 
			
		||||
				2A044C7012E761F900E0B624 /* Dropbox */,
 | 
			
		||||
				2A0C8CAF12EF851000A75AB7 /* FTP */,
 | 
			
		||||
				2A2F996212F095380069B37E /* SFTP */,
 | 
			
		||||
				2A5C1B0212F2FB09005153FA /* WebDav */,
 | 
			
		||||
@ -631,33 +502,6 @@
 | 
			
		||||
			name = Frameworks;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A044C5812E7613C00E0B624 /* Dropbox */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A044C5B12E7614C00E0B624 /* Info.plist */,
 | 
			
		||||
				2A4FA61412F9F8E9009F5B3A /* DropboxAccountPane.xib */,
 | 
			
		||||
			);
 | 
			
		||||
			path = Dropbox;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A044C6E12E761F300E0B624 /* Dropbox */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280E6812EB7A5D00435C36 /* DropboxSDK */,
 | 
			
		||||
				2A044C7112E7621B00E0B624 /* MGMDropboxPlugIn.h */,
 | 
			
		||||
				2A044C7212E7621B00E0B624 /* MGMDropboxPlugIn.m */,
 | 
			
		||||
			);
 | 
			
		||||
			path = Dropbox;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A044C7012E761F900E0B624 /* Dropbox */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A044C6F12E761F300E0B624 /* prefix.pch */,
 | 
			
		||||
			);
 | 
			
		||||
			name = Dropbox;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A0501C412F49A7B000F74EA /* MGMWebDav */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
@ -762,111 +606,6 @@
 | 
			
		||||
			name = FTP;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A280E6812EB7A5D00435C36 /* DropboxSDK */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280E6912EB7A5D00435C36 /* DBAccountInfo.h */,
 | 
			
		||||
				2A280E6A12EB7A5D00435C36 /* DBAccountInfo.m */,
 | 
			
		||||
				2A280E6D12EB7A5D00435C36 /* DBError.h */,
 | 
			
		||||
				2A280E6E12EB7A5D00435C36 /* DBError.m */,
 | 
			
		||||
				2A280E7312EB7A5D00435C36 /* DBMetadata.h */,
 | 
			
		||||
				2A280E7412EB7A5D00435C36 /* DBMetadata.m */,
 | 
			
		||||
				2A280E7512EB7A5D00435C36 /* DBQuota.h */,
 | 
			
		||||
				2A280E7612EB7A5D00435C36 /* DBQuota.m */,
 | 
			
		||||
				2A280E7712EB7A5E00435C36 /* DBRequest.h */,
 | 
			
		||||
				2A280E7812EB7A5E00435C36 /* DBRequest.m */,
 | 
			
		||||
				2A280E7912EB7A5E00435C36 /* DBRestClient.h */,
 | 
			
		||||
				2A280E7A12EB7A5E00435C36 /* DBRestClient.m */,
 | 
			
		||||
				2A280E7B12EB7A5E00435C36 /* DBSession.h */,
 | 
			
		||||
				2A280E7C12EB7A5E00435C36 /* DBSession.m */,
 | 
			
		||||
				2A280E7D12EB7A5E00435C36 /* DropboxSDK.h */,
 | 
			
		||||
				2A280E7E12EB7A5E00435C36 /* JSON */,
 | 
			
		||||
				2A280E8C12EB7A5E00435C36 /* MPOAuth */,
 | 
			
		||||
				2A280EB112EB7A5E00435C36 /* NSString+Dropbox.h */,
 | 
			
		||||
				2A280EB212EB7A5E00435C36 /* NSString+Dropbox.m */,
 | 
			
		||||
				2A280EB312EB7A5E00435C36 /* Resources */,
 | 
			
		||||
			);
 | 
			
		||||
			path = DropboxSDK;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A280E7E12EB7A5E00435C36 /* JSON */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280E7F12EB7A5E00435C36 /* JSON.h */,
 | 
			
		||||
				2A280E8012EB7A5E00435C36 /* NSObject+SBJSON.h */,
 | 
			
		||||
				2A280E8112EB7A5E00435C36 /* NSObject+SBJSON.m */,
 | 
			
		||||
				2A280E8212EB7A5E00435C36 /* NSString+SBJSON.h */,
 | 
			
		||||
				2A280E8312EB7A5E00435C36 /* NSString+SBJSON.m */,
 | 
			
		||||
				2A280E8412EB7A5E00435C36 /* SBJSON.h */,
 | 
			
		||||
				2A280E8512EB7A5E00435C36 /* SBJSON.m */,
 | 
			
		||||
				2A280E8612EB7A5E00435C36 /* SBJsonBase.h */,
 | 
			
		||||
				2A280E8712EB7A5E00435C36 /* SBJsonBase.m */,
 | 
			
		||||
				2A280E8812EB7A5E00435C36 /* SBJsonParser.h */,
 | 
			
		||||
				2A280E8912EB7A5E00435C36 /* SBJsonParser.m */,
 | 
			
		||||
				2A280E8A12EB7A5E00435C36 /* SBJsonWriter.h */,
 | 
			
		||||
				2A280E8B12EB7A5E00435C36 /* SBJsonWriter.m */,
 | 
			
		||||
			);
 | 
			
		||||
			path = JSON;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A280E8C12EB7A5E00435C36 /* MPOAuth */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280E8D12EB7A5E00435C36 /* Crypto */,
 | 
			
		||||
				2A280E9012EB7A5E00435C36 /* MPDebug.h */,
 | 
			
		||||
				2A280E9112EB7A5E00435C36 /* MPOAuth.h */,
 | 
			
		||||
				2A280E9212EB7A5E00435C36 /* MPOAuthAPI.h */,
 | 
			
		||||
				2A280E9312EB7A5E00435C36 /* MPOAuthAPI.m */,
 | 
			
		||||
				2A280E9412EB7A5E00435C36 /* MPOAuthAPIRequestLoader.h */,
 | 
			
		||||
				2A280E9512EB7A5E00435C36 /* MPOAuthAPIRequestLoader.m */,
 | 
			
		||||
				2A280E9612EB7A5E00435C36 /* MPOAuthAuthenticationMethod.h */,
 | 
			
		||||
				2A280E9712EB7A5E00435C36 /* MPOAuthAuthenticationMethod.m */,
 | 
			
		||||
				2A280E9812EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.h */,
 | 
			
		||||
				2A280E9912EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.m */,
 | 
			
		||||
				2A280E9A12EB7A5E00435C36 /* MPOAuthConnection.h */,
 | 
			
		||||
				2A280E9B12EB7A5E00435C36 /* MPOAuthConnection.m */,
 | 
			
		||||
				2A280E9C12EB7A5E00435C36 /* MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m */,
 | 
			
		||||
				2A280E9D12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditions.h */,
 | 
			
		||||
				2A280E9E12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m */,
 | 
			
		||||
				2A280E9F12EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.h */,
 | 
			
		||||
				2A280EA012EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.m */,
 | 
			
		||||
				2A280EA112EB7A5E00435C36 /* MPOAuthCredentialStore.h */,
 | 
			
		||||
				2A280EA212EB7A5E00435C36 /* MPOAuthParameterFactory.h */,
 | 
			
		||||
				2A280EA312EB7A5E00435C36 /* MPOAuthSignatureParameter.h */,
 | 
			
		||||
				2A280EA412EB7A5E00435C36 /* MPOAuthSignatureParameter.m */,
 | 
			
		||||
				2A280EA512EB7A5E00435C36 /* MPOAuthURLRequest.h */,
 | 
			
		||||
				2A280EA612EB7A5E00435C36 /* MPOAuthURLRequest.m */,
 | 
			
		||||
				2A280EA712EB7A5E00435C36 /* MPOAuthURLResponse.h */,
 | 
			
		||||
				2A280EA812EB7A5E00435C36 /* MPOAuthURLResponse.m */,
 | 
			
		||||
				2A280EA912EB7A5E00435C36 /* MPURLRequestParameter.h */,
 | 
			
		||||
				2A280EAA12EB7A5E00435C36 /* MPURLRequestParameter.m */,
 | 
			
		||||
				2A280EAB12EB7A5E00435C36 /* NSString+URLEscapingAdditions.h */,
 | 
			
		||||
				2A280EAC12EB7A5E00435C36 /* NSString+URLEscapingAdditions.m */,
 | 
			
		||||
				2A280EAD12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.h */,
 | 
			
		||||
				2A280EAE12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.m */,
 | 
			
		||||
				2A280EAF12EB7A5E00435C36 /* NSURLResponse+Encoding.h */,
 | 
			
		||||
				2A280EB012EB7A5E00435C36 /* NSURLResponse+Encoding.m */,
 | 
			
		||||
			);
 | 
			
		||||
			path = MPOAuth;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A280E8D12EB7A5E00435C36 /* Crypto */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280E8E12EB7A5E00435C36 /* Base64Transcoder.c */,
 | 
			
		||||
				2A280E8F12EB7A5E00435C36 /* Base64Transcoder.h */,
 | 
			
		||||
			);
 | 
			
		||||
			path = Crypto;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A280EB312EB7A5E00435C36 /* Resources */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A280EBD12EB7A5E00435C36 /* db_logo.png */,
 | 
			
		||||
			);
 | 
			
		||||
			path = Resources;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A2F996012F095320069B37E /* SFTP */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
@ -1004,7 +743,6 @@
 | 
			
		||||
			children = (
 | 
			
		||||
				2AEAB45C12E2ACEA00552BAA /* CocoaShare */,
 | 
			
		||||
				2A48847B12E67713001618B5 /* HTTP */,
 | 
			
		||||
				2A044C6E12E761F300E0B624 /* Dropbox */,
 | 
			
		||||
				2A0C8CAC12EF850900A75AB7 /* FTP */,
 | 
			
		||||
				2A2F996012F095320069B37E /* SFTP */,
 | 
			
		||||
				2A5C1AFF12F2FB04005153FA /* WebDav */,
 | 
			
		||||
@ -1060,7 +798,6 @@
 | 
			
		||||
			children = (
 | 
			
		||||
				2AEAB48212E2ADDF00552BAA /* CocoaShare */,
 | 
			
		||||
				2A48848712E67738001618B5 /* HTTP */,
 | 
			
		||||
				2A044C5812E7613C00E0B624 /* Dropbox */,
 | 
			
		||||
				2A0C8CAA12EF84FE00A75AB7 /* FTP */,
 | 
			
		||||
				2A2F996612F0955B0069B37E /* SFTP */,
 | 
			
		||||
				2A5C1AFD12F2FAF3005153FA /* WebDav */,
 | 
			
		||||
@ -1110,23 +847,6 @@
 | 
			
		||||
/* End PBXGroup section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXNativeTarget section */
 | 
			
		||||
		2A044C3F12E760DD00E0B624 /* Dropbox */ = {
 | 
			
		||||
			isa = PBXNativeTarget;
 | 
			
		||||
			buildConfigurationList = 2A044C4412E760E100E0B624 /* Build configuration list for PBXNativeTarget "Dropbox" */;
 | 
			
		||||
			buildPhases = (
 | 
			
		||||
				2A044C3C12E760DD00E0B624 /* Resources */,
 | 
			
		||||
				2A044C3D12E760DD00E0B624 /* Sources */,
 | 
			
		||||
				2A044C3E12E760DD00E0B624 /* Frameworks */,
 | 
			
		||||
			);
 | 
			
		||||
			buildRules = (
 | 
			
		||||
			);
 | 
			
		||||
			dependencies = (
 | 
			
		||||
			);
 | 
			
		||||
			name = Dropbox;
 | 
			
		||||
			productName = Dropbox;
 | 
			
		||||
			productReference = 2A044C4012E760DD00E0B624 /* Dropbox.bundle */;
 | 
			
		||||
			productType = "com.apple.product-type.bundle";
 | 
			
		||||
		};
 | 
			
		||||
		2A0501F012F49D08000F74EA /* MobileMe */ = {
 | 
			
		||||
			isa = PBXNativeTarget;
 | 
			
		||||
			buildConfigurationList = 2A0501F612F49D0C000F74EA /* Build configuration list for PBXNativeTarget "MobileMe" */;
 | 
			
		||||
@ -1261,7 +981,6 @@
 | 
			
		||||
			dependencies = (
 | 
			
		||||
				2AD9EFB312FEE51500FD7560 /* PBXTargetDependency */,
 | 
			
		||||
				2A48849812E679B6001618B5 /* PBXTargetDependency */,
 | 
			
		||||
				2A044C4C12E7611E00E0B624 /* PBXTargetDependency */,
 | 
			
		||||
				2A2F978C12F05C650069B37E /* PBXTargetDependency */,
 | 
			
		||||
				2A2F994C12F094EA0069B37E /* PBXTargetDependency */,
 | 
			
		||||
				2A5C1B4712F32EDF005153FA /* PBXTargetDependency */,
 | 
			
		||||
@ -1280,6 +999,8 @@
 | 
			
		||||
/* Begin PBXProject section */
 | 
			
		||||
		29B97313FDCFA39411CA2CEA /* Project object */ = {
 | 
			
		||||
			isa = PBXProject;
 | 
			
		||||
			attributes = {
 | 
			
		||||
			};
 | 
			
		||||
			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "CocoaShare" */;
 | 
			
		||||
			compatibilityVersion = "Xcode 3.1";
 | 
			
		||||
			developmentRegion = English;
 | 
			
		||||
@ -1301,7 +1022,6 @@
 | 
			
		||||
			targets = (
 | 
			
		||||
				8D1107260486CEB800E47090 /* CocoaShare */,
 | 
			
		||||
				2A48847512E6768D001618B5 /* HTTP */,
 | 
			
		||||
				2A044C3F12E760DD00E0B624 /* Dropbox */,
 | 
			
		||||
				2A0C8C9312EF844F00A75AB7 /* FTP */,
 | 
			
		||||
				2A2F994412F094710069B37E /* SFTP */,
 | 
			
		||||
				2A5C1AF212F2FA6F005153FA /* WebDav */,
 | 
			
		||||
@ -1314,15 +1034,6 @@
 | 
			
		||||
/* End PBXProject section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXResourcesBuildPhase section */
 | 
			
		||||
		2A044C3C12E760DD00E0B624 /* Resources */ = {
 | 
			
		||||
			isa = PBXResourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				2A4FA61512F9F8E9009F5B3A /* DropboxAccountPane.xib in Resources */,
 | 
			
		||||
				2A280EE912EB7A5E00435C36 /* db_logo.png in Resources */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501ED12F49D08000F74EA /* Resources */ = {
 | 
			
		||||
			isa = PBXResourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
@ -1427,44 +1138,6 @@
 | 
			
		||||
/* End PBXShellScriptBuildPhase section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXSourcesBuildPhase section */
 | 
			
		||||
		2A044C3D12E760DD00E0B624 /* Sources */ = {
 | 
			
		||||
			isa = PBXSourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
			files = (
 | 
			
		||||
				2A044CE712E768D500E0B624 /* MGMDropboxPlugIn.m in Sources */,
 | 
			
		||||
				2A280EBF12EB7A5E00435C36 /* DBAccountInfo.m in Sources */,
 | 
			
		||||
				2A280EC112EB7A5E00435C36 /* DBError.m in Sources */,
 | 
			
		||||
				2A280EC412EB7A5E00435C36 /* DBMetadata.m in Sources */,
 | 
			
		||||
				2A280EC512EB7A5E00435C36 /* DBQuota.m in Sources */,
 | 
			
		||||
				2A280EC612EB7A5E00435C36 /* DBRequest.m in Sources */,
 | 
			
		||||
				2A280EC712EB7A5E00435C36 /* DBRestClient.m in Sources */,
 | 
			
		||||
				2A280EC812EB7A5E00435C36 /* DBSession.m in Sources */,
 | 
			
		||||
				2A280EC912EB7A5E00435C36 /* NSObject+SBJSON.m in Sources */,
 | 
			
		||||
				2A280ECA12EB7A5E00435C36 /* NSString+SBJSON.m in Sources */,
 | 
			
		||||
				2A280ECB12EB7A5E00435C36 /* SBJSON.m in Sources */,
 | 
			
		||||
				2A280ECC12EB7A5E00435C36 /* SBJsonBase.m in Sources */,
 | 
			
		||||
				2A280ECD12EB7A5E00435C36 /* SBJsonParser.m in Sources */,
 | 
			
		||||
				2A280ECE12EB7A5E00435C36 /* SBJsonWriter.m in Sources */,
 | 
			
		||||
				2A280ECF12EB7A5E00435C36 /* Base64Transcoder.c in Sources */,
 | 
			
		||||
				2A280ED012EB7A5E00435C36 /* MPOAuthAPI.m in Sources */,
 | 
			
		||||
				2A280ED112EB7A5E00435C36 /* MPOAuthAPIRequestLoader.m in Sources */,
 | 
			
		||||
				2A280ED212EB7A5E00435C36 /* MPOAuthAuthenticationMethod.m in Sources */,
 | 
			
		||||
				2A280ED312EB7A5E00435C36 /* MPOAuthAuthenticationMethodOAuth.m in Sources */,
 | 
			
		||||
				2A280ED412EB7A5E00435C36 /* MPOAuthConnection.m in Sources */,
 | 
			
		||||
				2A280ED512EB7A5E00435C36 /* MPOAuthCredentiaIConcreteStore+KeychainAdditionsMac.m in Sources */,
 | 
			
		||||
				2A280ED612EB7A5E00435C36 /* MPOAuthCredentialConcreteStore+KeychainAdditionsiPhone.m in Sources */,
 | 
			
		||||
				2A280ED712EB7A5E00435C36 /* MPOAuthCredentialConcreteStore.m in Sources */,
 | 
			
		||||
				2A280ED812EB7A5E00435C36 /* MPOAuthSignatureParameter.m in Sources */,
 | 
			
		||||
				2A280ED912EB7A5E00435C36 /* MPOAuthURLRequest.m in Sources */,
 | 
			
		||||
				2A280EDA12EB7A5E00435C36 /* MPOAuthURLResponse.m in Sources */,
 | 
			
		||||
				2A280EDB12EB7A5E00435C36 /* MPURLRequestParameter.m in Sources */,
 | 
			
		||||
				2A280EDC12EB7A5E00435C36 /* NSString+URLEscapingAdditions.m in Sources */,
 | 
			
		||||
				2A280EDD12EB7A5E00435C36 /* NSURL+MPURLParameterAdditions.m in Sources */,
 | 
			
		||||
				2A280EDE12EB7A5E00435C36 /* NSURLResponse+Encoding.m in Sources */,
 | 
			
		||||
				2A280EDF12EB7A5E00435C36 /* NSString+Dropbox.m in Sources */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501EE12F49D08000F74EA /* Sources */ = {
 | 
			
		||||
			isa = PBXSourcesBuildPhase;
 | 
			
		||||
			buildActionMask = 2147483647;
 | 
			
		||||
@ -1553,11 +1226,6 @@
 | 
			
		||||
/* End PBXSourcesBuildPhase section */
 | 
			
		||||
 | 
			
		||||
/* Begin PBXTargetDependency section */
 | 
			
		||||
		2A044C4C12E7611E00E0B624 /* PBXTargetDependency */ = {
 | 
			
		||||
			isa = PBXTargetDependency;
 | 
			
		||||
			target = 2A044C3F12E760DD00E0B624 /* Dropbox */;
 | 
			
		||||
			targetProxy = 2A044C4B12E7611E00E0B624 /* PBXContainerItemProxy */;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501FA12F49D54000F74EA /* PBXTargetDependency */ = {
 | 
			
		||||
			isa = PBXTargetDependency;
 | 
			
		||||
			target = 2A0501F012F49D08000F74EA /* MobileMe */;
 | 
			
		||||
@ -1622,16 +1290,6 @@
 | 
			
		||||
			name = HTTPAccountPane.xib;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A4FA61412F9F8E9009F5B3A /* DropboxAccountPane.xib */ = {
 | 
			
		||||
			isa = PBXVariantGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				2A044C7812E762D100E0B624 /* English */,
 | 
			
		||||
				2A4C784312FC3A7400106ECD /* pt_PT */,
 | 
			
		||||
				2A1E47B1130966CC00102EBD /* sv */,
 | 
			
		||||
			);
 | 
			
		||||
			name = DropboxAccountPane.xib;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
		};
 | 
			
		||||
		2A4FA61612F9F8F0009F5B3A /* FTPAccountPane.xib */ = {
 | 
			
		||||
			isa = PBXVariantGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
@ -1763,56 +1421,6 @@
 | 
			
		||||
/* End PBXVariantGroup section */
 | 
			
		||||
 | 
			
		||||
/* Begin XCBuildConfiguration section */
 | 
			
		||||
		2A044C4212E760E000E0B624 /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ALWAYS_SEARCH_USER_PATHS = NO;
 | 
			
		||||
				COPY_PHASE_STRIP = NO;
 | 
			
		||||
				GCC_DYNAMIC_NO_PIC = NO;
 | 
			
		||||
				GCC_ENABLE_FIX_AND_CONTINUE = YES;
 | 
			
		||||
				GCC_MODEL_TUNING = G5;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = 0;
 | 
			
		||||
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 | 
			
		||||
				GCC_PREFIX_HEADER = Classes/Dropbox/prefix.pch;
 | 
			
		||||
				INFOPLIST_FILE = Resources/Dropbox/Info.plist;
 | 
			
		||||
				INSTALL_PATH = "$(HOME)/Library/Bundles";
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-undefined",
 | 
			
		||||
					suppress,
 | 
			
		||||
					"-undefined",
 | 
			
		||||
					dynamic_lookup,
 | 
			
		||||
				);
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				PRODUCT_NAME = Dropbox;
 | 
			
		||||
				WRAPPER_EXTENSION = bundle;
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
		};
 | 
			
		||||
		2A044C4312E760E000E0B624 /* Release */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ALWAYS_SEARCH_USER_PATHS = NO;
 | 
			
		||||
				COPY_PHASE_STRIP = YES;
 | 
			
		||||
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 | 
			
		||||
				GCC_ENABLE_FIX_AND_CONTINUE = NO;
 | 
			
		||||
				GCC_MODEL_TUNING = G5;
 | 
			
		||||
				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 | 
			
		||||
				GCC_PREFIX_HEADER = Classes/Dropbox/prefix.pch;
 | 
			
		||||
				INFOPLIST_FILE = Resources/Dropbox/Info.plist;
 | 
			
		||||
				INSTALL_PATH = "$(HOME)/Library/Bundles";
 | 
			
		||||
				OTHER_LDFLAGS = (
 | 
			
		||||
					"-undefined",
 | 
			
		||||
					suppress,
 | 
			
		||||
					"-undefined",
 | 
			
		||||
					dynamic_lookup,
 | 
			
		||||
				);
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				PRODUCT_NAME = Dropbox;
 | 
			
		||||
				WRAPPER_EXTENSION = bundle;
 | 
			
		||||
				ZERO_LINK = NO;
 | 
			
		||||
			};
 | 
			
		||||
			name = Release;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501F412F49D0B000F74EA /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
@ -2258,21 +1866,17 @@
 | 
			
		||||
		C01FCF4F08A954540054247B /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ARCHS = (
 | 
			
		||||
					ppc,
 | 
			
		||||
					i386,
 | 
			
		||||
					x86_64,
 | 
			
		||||
				);
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 | 
			
		||||
				GCC_C_LANGUAGE_STANDARD = gnu99;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = 0;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvmgcc42;
 | 
			
		||||
				GCC_VERSION = "";
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				MACOSX_DEPLOYMENT_TARGET = 10.4;
 | 
			
		||||
				"MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5;
 | 
			
		||||
				ONLY_ACTIVE_ARCH = YES;
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				SDKROOT = macosx10.5;
 | 
			
		||||
				SDKROOT = macosx;
 | 
			
		||||
				VALID_ARCHS = "ppc i386 x86_64";
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
@ -2280,19 +1884,15 @@
 | 
			
		||||
		C01FCF5008A954540054247B /* Release */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ARCHS = (
 | 
			
		||||
					ppc,
 | 
			
		||||
					i386,
 | 
			
		||||
					x86_64,
 | 
			
		||||
				);
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 | 
			
		||||
				GCC_C_LANGUAGE_STANDARD = gnu99;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvmgcc42;
 | 
			
		||||
				GCC_VERSION = "";
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				MACOSX_DEPLOYMENT_TARGET = 10.4;
 | 
			
		||||
				"MACOSX_DEPLOYMENT_TARGET[arch=x86_64]" = 10.5;
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				SDKROOT = macosx10.5;
 | 
			
		||||
				SDKROOT = macosx;
 | 
			
		||||
				VALID_ARCHS = "ppc i386 x86_64";
 | 
			
		||||
			};
 | 
			
		||||
			name = Release;
 | 
			
		||||
@ -2300,15 +1900,6 @@
 | 
			
		||||
/* End XCBuildConfiguration section */
 | 
			
		||||
 | 
			
		||||
/* Begin XCConfigurationList section */
 | 
			
		||||
		2A044C4412E760E100E0B624 /* Build configuration list for PBXNativeTarget "Dropbox" */ = {
 | 
			
		||||
			isa = XCConfigurationList;
 | 
			
		||||
			buildConfigurations = (
 | 
			
		||||
				2A044C4212E760E000E0B624 /* Debug */,
 | 
			
		||||
				2A044C4312E760E000E0B624 /* Release */,
 | 
			
		||||
			);
 | 
			
		||||
			defaultConfigurationIsVisible = 0;
 | 
			
		||||
			defaultConfigurationName = Release;
 | 
			
		||||
		};
 | 
			
		||||
		2A0501F612F49D0C000F74EA /* Build configuration list for PBXNativeTarget "MobileMe" */ = {
 | 
			
		||||
			isa = XCConfigurationList;
 | 
			
		||||
			buildConfigurations = (
 | 
			
		||||
@ -2370,6 +1961,7 @@
 | 
			
		||||
				2ACA5CD3160E763A00F294C2 /* Release */,
 | 
			
		||||
			);
 | 
			
		||||
			defaultConfigurationIsVisible = 0;
 | 
			
		||||
			defaultConfigurationName = Release;
 | 
			
		||||
		};
 | 
			
		||||
		2AD9EFAE12FEE24000FD7560 /* Build configuration list for PBXAggregateTarget "Build Directory" */ = {
 | 
			
		||||
			isa = XCConfigurationList;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,53 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
	<key>IDESourceControlProjectFavoriteDictionaryKey</key>
 | 
			
		||||
	<false/>
 | 
			
		||||
	<key>IDESourceControlProjectIdentifier</key>
 | 
			
		||||
	<string>334F6FCC-850E-4ACB-B8A5-A74C9642A6EE</string>
 | 
			
		||||
	<key>IDESourceControlProjectName</key>
 | 
			
		||||
	<string>CocoaShare</string>
 | 
			
		||||
	<key>IDESourceControlProjectOriginsDictionary</key>
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9</key>
 | 
			
		||||
		<string>mrgeckosmedia.com:public/CocoaShare</string>
 | 
			
		||||
		<key>FC64668886F843E3F3F1528DF74D9C3877AA42A0</key>
 | 
			
		||||
		<string>mrgeckosmedia.com:public/GeckoReporter</string>
 | 
			
		||||
	</dict>
 | 
			
		||||
	<key>IDESourceControlProjectPath</key>
 | 
			
		||||
	<string>CocoaShare.xcodeproj</string>
 | 
			
		||||
	<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9</key>
 | 
			
		||||
		<string>../..</string>
 | 
			
		||||
		<key>FC64668886F843E3F3F1528DF74D9C3877AA42A0</key>
 | 
			
		||||
		<string>../../../GeckoReporter</string>
 | 
			
		||||
	</dict>
 | 
			
		||||
	<key>IDESourceControlProjectURL</key>
 | 
			
		||||
	<string>mrgeckosmedia.com:public/CocoaShare</string>
 | 
			
		||||
	<key>IDESourceControlProjectVersion</key>
 | 
			
		||||
	<integer>111</integer>
 | 
			
		||||
	<key>IDESourceControlProjectWCCIdentifier</key>
 | 
			
		||||
	<string>3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9</string>
 | 
			
		||||
	<key>IDESourceControlProjectWCConfigurations</key>
 | 
			
		||||
	<array>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
 | 
			
		||||
			<string>public.vcs.git</string>
 | 
			
		||||
			<key>IDESourceControlWCCIdentifierKey</key>
 | 
			
		||||
			<string>3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9</string>
 | 
			
		||||
			<key>IDESourceControlWCCName</key>
 | 
			
		||||
			<string>CocoaShare</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
 | 
			
		||||
			<string>public.vcs.git</string>
 | 
			
		||||
			<key>IDESourceControlWCCIdentifierKey</key>
 | 
			
		||||
			<string>FC64668886F843E3F3F1528DF74D9C3877AA42A0</string>
 | 
			
		||||
			<key>IDESourceControlWCCName</key>
 | 
			
		||||
			<string>GeckoReporter</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
	</array>
 | 
			
		||||
</dict>
 | 
			
		||||
</plist>
 | 
			
		||||
@ -0,0 +1,30 @@
 | 
			
		||||
{
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9",
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
 | 
			
		||||
    "FC64668886F843E3F3F1528DF74D9C3877AA42A0" : 0,
 | 
			
		||||
    "3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9" : 0
 | 
			
		||||
  },
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "334F6FCC-850E-4ACB-B8A5-A74C9642A6EE",
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
 | 
			
		||||
    "FC64668886F843E3F3F1528DF74D9C3877AA42A0" : "GeckoReporter",
 | 
			
		||||
    "3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9" : "CocoaShare"
 | 
			
		||||
  },
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintNameKey" : "CocoaShare",
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintVersion" : 204,
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CocoaShare.xcodeproj",
 | 
			
		||||
  "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
 | 
			
		||||
    {
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "mrgeckosmedia.com:public\/CocoaShare",
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3FBB0551AFF4DBDC5FAA2B71A26D0488BDD753D9"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "mrgeckosmedia.com:public\/GeckoReporter",
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
 | 
			
		||||
      "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "FC64668886F843E3F3F1528DF74D9C3877AA42A0"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@ -34,11 +34,11 @@
 | 
			
		||||
	<key>CFBundlePackageType</key>
 | 
			
		||||
	<string>APPL</string>
 | 
			
		||||
	<key>CFBundleShortVersionString</key>
 | 
			
		||||
	<string>0.1</string>
 | 
			
		||||
	<string>0.2</string>
 | 
			
		||||
	<key>CFBundleSignature</key>
 | 
			
		||||
	<string>????</string>
 | 
			
		||||
	<key>CFBundleVersion</key>
 | 
			
		||||
	<string>0.1</string>
 | 
			
		||||
	<string>0.3</string>
 | 
			
		||||
	<key>LSMinimumSystemVersion</key>
 | 
			
		||||
	<string>${MACOSX_DEPLOYMENT_TARGET}</string>
 | 
			
		||||
	<key>MGMGRBugsEmail</key>
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.6 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.4 KiB  | 
@ -1,26 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
<plist version="1.0">
 | 
			
		||||
<dict>
 | 
			
		||||
	<key>CFBundleDevelopmentRegion</key>
 | 
			
		||||
	<string>English</string>
 | 
			
		||||
	<key>CFBundleExecutable</key>
 | 
			
		||||
	<string>${EXECUTABLE_NAME}</string>
 | 
			
		||||
	<key>CFBundleIdentifier</key>
 | 
			
		||||
	<string>com.MrGeckosMedia.${PRODUCT_NAME:rfc1034identifier}</string>
 | 
			
		||||
	<key>CFBundleInfoDictionaryVersion</key>
 | 
			
		||||
	<string>6.0</string>
 | 
			
		||||
	<key>CFBundlePackageType</key>
 | 
			
		||||
	<string>BNDL</string>
 | 
			
		||||
	<key>CFBundleShortVersionString</key>
 | 
			
		||||
	<string>0.1</string>
 | 
			
		||||
	<key>CFBundleSignature</key>
 | 
			
		||||
	<string>????</string>
 | 
			
		||||
	<key>CFBundleVersion</key>
 | 
			
		||||
	<string>0.1</string>
 | 
			
		||||
	<key>NSPrincipalClass</key>
 | 
			
		||||
	<string>MGMDropboxPlugIn</string>
 | 
			
		||||
	<key>NSHumanReadableCopyright</key>
 | 
			
		||||
	<string>Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/</string>
 | 
			
		||||
</dict>
 | 
			
		||||
</plist>
 | 
			
		||||
@ -1,866 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
 | 
			
		||||
	<data>
 | 
			
		||||
		<int key="IBDocument.SystemTarget">1050</int>
 | 
			
		||||
		<string key="IBDocument.SystemVersion">10J567</string>
 | 
			
		||||
		<string key="IBDocument.InterfaceBuilderVersion">1294</string>
 | 
			
		||||
		<string key="IBDocument.AppKitVersion">1038.35</string>
 | 
			
		||||
		<string key="IBDocument.HIToolboxVersion">462.00</string>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
			<string key="NS.object.0">1294</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<string>NSScroller</string>
 | 
			
		||||
			<string>NSImageView</string>
 | 
			
		||||
			<string>NSScrollView</string>
 | 
			
		||||
			<string>NSTextField</string>
 | 
			
		||||
			<string>NSOutlineView</string>
 | 
			
		||||
			<string>NSCustomObject</string>
 | 
			
		||||
			<string>NSCustomView</string>
 | 
			
		||||
			<string>NSButtonCell</string>
 | 
			
		||||
			<string>NSButton</string>
 | 
			
		||||
			<string>NSImageCell</string>
 | 
			
		||||
			<string>NSSecureTextFieldCell</string>
 | 
			
		||||
			<string>NSTableColumn</string>
 | 
			
		||||
			<string>NSTextFieldCell</string>
 | 
			
		||||
			<string>NSSecureTextField</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSArray" key="IBDocument.PluginDependencies">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.Metadata">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<object class="NSArray" key="dict.sortedKeys" id="0">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			</object>
 | 
			
		||||
			<reference key="dict.values" ref="0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<object class="NSCustomObject" id="1001">
 | 
			
		||||
				<string key="NSClassName">MGMDropboxPlugIn</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSCustomObject" id="1003">
 | 
			
		||||
				<string key="NSClassName">FirstResponder</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSCustomObject" id="1004">
 | 
			
		||||
				<string key="NSClassName">NSApplication</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSCustomView" id="1005">
 | 
			
		||||
				<reference key="NSNextResponder"/>
 | 
			
		||||
				<int key="NSvFlags">268</int>
 | 
			
		||||
				<object class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<object class="NSImageView" id="159969733">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">256</int>
 | 
			
		||||
						<object class="NSMutableSet" key="NSDragTypes">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<object class="NSArray" key="set.sortedObjects">
 | 
			
		||||
								<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
								<string>Apple PDF pasteboard type</string>
 | 
			
		||||
								<string>Apple PICT pasteboard type</string>
 | 
			
		||||
								<string>Apple PNG pasteboard type</string>
 | 
			
		||||
								<string>NSFilenamesPboardType</string>
 | 
			
		||||
								<string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
 | 
			
		||||
								<string>NeXT TIFF v4.0 pasteboard type</string>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
						<string key="NSFrame">{{20, 103}, {116, 32}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="166222988"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSImageCell" key="NSCell" id="719969108">
 | 
			
		||||
							<int key="NSCellFlags">130560</int>
 | 
			
		||||
							<int key="NSCellFlags2">33554432</int>
 | 
			
		||||
							<object class="NSCustomResource" key="NSContents">
 | 
			
		||||
								<string key="NSClassName">NSImage</string>
 | 
			
		||||
								<string key="NSResourceName">db_logo</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<int key="NSAlign">0</int>
 | 
			
		||||
							<int key="NSScale">0</int>
 | 
			
		||||
							<int key="NSStyle">0</int>
 | 
			
		||||
							<bool key="NSAnimates">YES</bool>
 | 
			
		||||
						</object>
 | 
			
		||||
						<bool key="NSEditable">YES</bool>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSButton" id="166222988">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<string key="NSFrame">{{215, 101}, {108, 32}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="512917876"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSButtonCell" key="NSCell" id="549737638">
 | 
			
		||||
							<int key="NSCellFlags">67239424</int>
 | 
			
		||||
							<int key="NSCellFlags2">134217728</int>
 | 
			
		||||
							<string key="NSContents">Inloggning</string>
 | 
			
		||||
							<object class="NSFont" key="NSSupport" id="902206146">
 | 
			
		||||
								<string key="NSName">LucidaGrande</string>
 | 
			
		||||
								<double key="NSSize">13</double>
 | 
			
		||||
								<int key="NSfFlags">1044</int>
 | 
			
		||||
							</object>
 | 
			
		||||
							<reference key="NSControlView" ref="166222988"/>
 | 
			
		||||
							<int key="NSButtonFlags">-2038284033</int>
 | 
			
		||||
							<int key="NSButtonFlags2">129</int>
 | 
			
		||||
							<string key="NSAlternateContents"/>
 | 
			
		||||
							<string type="base64-UTF8" key="NSKeyEquivalent">DQ</string>
 | 
			
		||||
							<int key="NSPeriodicDelay">200</int>
 | 
			
		||||
							<int key="NSPeriodicInterval">25</int>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSScrollView" id="512917876">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<object class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<object class="NSClipView" id="942248106">
 | 
			
		||||
								<reference key="NSNextResponder" ref="512917876"/>
 | 
			
		||||
								<int key="NSvFlags">2304</int>
 | 
			
		||||
								<object class="NSMutableArray" key="NSSubviews">
 | 
			
		||||
									<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
									<object class="NSOutlineView" id="472926426">
 | 
			
		||||
										<reference key="NSNextResponder" ref="942248106"/>
 | 
			
		||||
										<int key="NSvFlags">256</int>
 | 
			
		||||
										<string key="NSFrameSize">{335, 95}</string>
 | 
			
		||||
										<reference key="NSSuperview" ref="942248106"/>
 | 
			
		||||
										<reference key="NSWindow"/>
 | 
			
		||||
										<reference key="NSNextKeyView" ref="467645476"/>
 | 
			
		||||
										<bool key="NSEnabled">YES</bool>
 | 
			
		||||
										<object class="_NSCornerView" key="NSCornerView">
 | 
			
		||||
											<nil key="NSNextResponder"/>
 | 
			
		||||
											<int key="NSvFlags">-2147483392</int>
 | 
			
		||||
											<string key="NSFrame">{{224, 0}, {16, 17}}</string>
 | 
			
		||||
										</object>
 | 
			
		||||
										<object class="NSMutableArray" key="NSTableColumns">
 | 
			
		||||
											<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
											<object class="NSTableColumn" id="24135004">
 | 
			
		||||
												<string key="NSIdentifier">selected</string>
 | 
			
		||||
												<double key="NSWidth">30</double>
 | 
			
		||||
												<double key="NSMinWidth">30</double>
 | 
			
		||||
												<double key="NSMaxWidth">1000</double>
 | 
			
		||||
												<object class="NSTableHeaderCell" key="NSHeaderCell">
 | 
			
		||||
													<int key="NSCellFlags">75628096</int>
 | 
			
		||||
													<int key="NSCellFlags2">2048</int>
 | 
			
		||||
													<string key="NSContents"/>
 | 
			
		||||
													<object class="NSFont" key="NSSupport" id="26">
 | 
			
		||||
														<string key="NSName">LucidaGrande</string>
 | 
			
		||||
														<double key="NSSize">11</double>
 | 
			
		||||
														<int key="NSfFlags">3100</int>
 | 
			
		||||
													</object>
 | 
			
		||||
													<object class="NSColor" key="NSBackgroundColor" id="1028014805">
 | 
			
		||||
														<int key="NSColorSpace">3</int>
 | 
			
		||||
														<bytes key="NSWhite">MC4zMzMzMzI5ODU2AA</bytes>
 | 
			
		||||
													</object>
 | 
			
		||||
													<object class="NSColor" key="NSTextColor" id="275244432">
 | 
			
		||||
														<int key="NSColorSpace">6</int>
 | 
			
		||||
														<string key="NSCatalogName">System</string>
 | 
			
		||||
														<string key="NSColorName">headerTextColor</string>
 | 
			
		||||
														<object class="NSColor" key="NSColor" id="342700193">
 | 
			
		||||
															<int key="NSColorSpace">3</int>
 | 
			
		||||
															<bytes key="NSWhite">MAA</bytes>
 | 
			
		||||
														</object>
 | 
			
		||||
													</object>
 | 
			
		||||
												</object>
 | 
			
		||||
												<object class="NSButtonCell" key="NSDataCell" id="1048517996">
 | 
			
		||||
													<int key="NSCellFlags">67239424</int>
 | 
			
		||||
													<int key="NSCellFlags2">0</int>
 | 
			
		||||
													<string key="NSContents">Check</string>
 | 
			
		||||
													<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
													<reference key="NSControlView" ref="472926426"/>
 | 
			
		||||
													<int key="NSButtonFlags">1215582719</int>
 | 
			
		||||
													<int key="NSButtonFlags2">2</int>
 | 
			
		||||
													<object class="NSCustomResource" key="NSNormalImage">
 | 
			
		||||
														<string key="NSClassName">NSImage</string>
 | 
			
		||||
														<string key="NSResourceName">NSSwitch</string>
 | 
			
		||||
													</object>
 | 
			
		||||
													<object class="NSButtonImageSource" key="NSAlternateImage">
 | 
			
		||||
														<string key="NSImageName">NSSwitch</string>
 | 
			
		||||
													</object>
 | 
			
		||||
													<string key="NSAlternateContents"/>
 | 
			
		||||
													<string key="NSKeyEquivalent"/>
 | 
			
		||||
													<int key="NSPeriodicDelay">200</int>
 | 
			
		||||
													<int key="NSPeriodicInterval">25</int>
 | 
			
		||||
												</object>
 | 
			
		||||
												<int key="NSResizingMask">3</int>
 | 
			
		||||
												<bool key="NSIsResizeable">YES</bool>
 | 
			
		||||
												<bool key="NSIsEditable">YES</bool>
 | 
			
		||||
												<reference key="NSTableView" ref="472926426"/>
 | 
			
		||||
											</object>
 | 
			
		||||
											<object class="NSTableColumn" id="196057634">
 | 
			
		||||
												<string key="NSIdentifier">name</string>
 | 
			
		||||
												<double key="NSWidth">299</double>
 | 
			
		||||
												<double key="NSMinWidth">16</double>
 | 
			
		||||
												<double key="NSMaxWidth">1000</double>
 | 
			
		||||
												<object class="NSTableHeaderCell" key="NSHeaderCell">
 | 
			
		||||
													<int key="NSCellFlags">75628096</int>
 | 
			
		||||
													<int key="NSCellFlags2">2048</int>
 | 
			
		||||
													<string key="NSContents"/>
 | 
			
		||||
													<reference key="NSSupport" ref="26"/>
 | 
			
		||||
													<reference key="NSBackgroundColor" ref="1028014805"/>
 | 
			
		||||
													<reference key="NSTextColor" ref="275244432"/>
 | 
			
		||||
												</object>
 | 
			
		||||
												<object class="NSTextFieldCell" key="NSDataCell" id="850771707">
 | 
			
		||||
													<int key="NSCellFlags">337772096</int>
 | 
			
		||||
													<int key="NSCellFlags2">2048</int>
 | 
			
		||||
													<string key="NSContents">Text Cell</string>
 | 
			
		||||
													<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
													<reference key="NSControlView" ref="472926426"/>
 | 
			
		||||
													<object class="NSColor" key="NSBackgroundColor" id="172809521">
 | 
			
		||||
														<int key="NSColorSpace">6</int>
 | 
			
		||||
														<string key="NSCatalogName">System</string>
 | 
			
		||||
														<string key="NSColorName">controlBackgroundColor</string>
 | 
			
		||||
														<object class="NSColor" key="NSColor" id="859429791">
 | 
			
		||||
															<int key="NSColorSpace">3</int>
 | 
			
		||||
															<bytes key="NSWhite">MC42NjY2NjY2ODY1AA</bytes>
 | 
			
		||||
														</object>
 | 
			
		||||
													</object>
 | 
			
		||||
													<object class="NSColor" key="NSTextColor" id="888636459">
 | 
			
		||||
														<int key="NSColorSpace">6</int>
 | 
			
		||||
														<string key="NSCatalogName">System</string>
 | 
			
		||||
														<string key="NSColorName">controlTextColor</string>
 | 
			
		||||
														<reference key="NSColor" ref="342700193"/>
 | 
			
		||||
													</object>
 | 
			
		||||
												</object>
 | 
			
		||||
												<int key="NSResizingMask">3</int>
 | 
			
		||||
												<bool key="NSIsResizeable">YES</bool>
 | 
			
		||||
												<reference key="NSTableView" ref="472926426"/>
 | 
			
		||||
											</object>
 | 
			
		||||
										</object>
 | 
			
		||||
										<double key="NSIntercellSpacingWidth">3</double>
 | 
			
		||||
										<double key="NSIntercellSpacingHeight">2</double>
 | 
			
		||||
										<object class="NSColor" key="NSBackgroundColor" id="112253361">
 | 
			
		||||
											<int key="NSColorSpace">3</int>
 | 
			
		||||
											<bytes key="NSWhite">MQA</bytes>
 | 
			
		||||
										</object>
 | 
			
		||||
										<object class="NSColor" key="NSGridColor">
 | 
			
		||||
											<int key="NSColorSpace">6</int>
 | 
			
		||||
											<string key="NSCatalogName">System</string>
 | 
			
		||||
											<string key="NSColorName">gridColor</string>
 | 
			
		||||
											<object class="NSColor" key="NSColor">
 | 
			
		||||
												<int key="NSColorSpace">3</int>
 | 
			
		||||
												<bytes key="NSWhite">MC41AA</bytes>
 | 
			
		||||
											</object>
 | 
			
		||||
										</object>
 | 
			
		||||
										<double key="NSRowHeight">17</double>
 | 
			
		||||
										<int key="NSTvFlags">-767557632</int>
 | 
			
		||||
										<reference key="NSDelegate"/>
 | 
			
		||||
										<reference key="NSDataSource"/>
 | 
			
		||||
										<int key="NSColumnAutoresizingStyle">4</int>
 | 
			
		||||
										<int key="NSDraggingSourceMaskForLocal">15</int>
 | 
			
		||||
										<int key="NSDraggingSourceMaskForNonLocal">0</int>
 | 
			
		||||
										<bool key="NSAllowsTypeSelect">YES</bool>
 | 
			
		||||
										<int key="NSTableViewDraggingDestinationStyle">0</int>
 | 
			
		||||
										<reference key="NSOutlineViewOutlineTableColumnKey" ref="196057634"/>
 | 
			
		||||
									</object>
 | 
			
		||||
								</object>
 | 
			
		||||
								<string key="NSFrame">{{1, 1}, {335, 95}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="512917876"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView" ref="472926426"/>
 | 
			
		||||
								<reference key="NSDocView" ref="472926426"/>
 | 
			
		||||
								<reference key="NSBGColor" ref="172809521"/>
 | 
			
		||||
								<int key="NScvFlags">4</int>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="NSScroller" id="467645476">
 | 
			
		||||
								<reference key="NSNextResponder" ref="512917876"/>
 | 
			
		||||
								<int key="NSvFlags">-2147483392</int>
 | 
			
		||||
								<string key="NSFrame">{{224, 17}, {15, 102}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="512917876"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView" ref="643577797"/>
 | 
			
		||||
								<reference key="NSTarget" ref="512917876"/>
 | 
			
		||||
								<string key="NSAction">_doScroller:</string>
 | 
			
		||||
								<double key="NSPercent">0.9929078221321106</double>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="NSScroller" id="643577797">
 | 
			
		||||
								<reference key="NSNextResponder" ref="512917876"/>
 | 
			
		||||
								<int key="NSvFlags">-2147483392</int>
 | 
			
		||||
								<string key="NSFrame">{{1, 119}, {238, 15}}</string>
 | 
			
		||||
								<reference key="NSSuperview" ref="512917876"/>
 | 
			
		||||
								<reference key="NSWindow"/>
 | 
			
		||||
								<reference key="NSNextKeyView"/>
 | 
			
		||||
								<int key="NSsFlags">1</int>
 | 
			
		||||
								<reference key="NSTarget" ref="512917876"/>
 | 
			
		||||
								<string key="NSAction">_doScroller:</string>
 | 
			
		||||
								<double key="NSPercent">0.9970238208770752</double>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
						<string key="NSFrame">{{0, -2}, {337, 97}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="942248106"/>
 | 
			
		||||
						<int key="NSsFlags">562</int>
 | 
			
		||||
						<reference key="NSVScroller" ref="467645476"/>
 | 
			
		||||
						<reference key="NSHScroller" ref="643577797"/>
 | 
			
		||||
						<reference key="NSContentView" ref="942248106"/>
 | 
			
		||||
						<bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSSecureTextField" id="1968599">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<string key="NSFrame">{{90, 137}, {227, 22}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="159969733"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSSecureTextFieldCell" key="NSCell" id="106272887">
 | 
			
		||||
							<int key="NSCellFlags">343014976</int>
 | 
			
		||||
							<int key="NSCellFlags2">272630784</int>
 | 
			
		||||
							<string key="NSContents"/>
 | 
			
		||||
							<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
							<reference key="NSControlView" ref="1968599"/>
 | 
			
		||||
							<bool key="NSDrawsBackground">YES</bool>
 | 
			
		||||
							<object class="NSColor" key="NSBackgroundColor" id="817216621">
 | 
			
		||||
								<int key="NSColorSpace">6</int>
 | 
			
		||||
								<string key="NSCatalogName">System</string>
 | 
			
		||||
								<string key="NSColorName">textBackgroundColor</string>
 | 
			
		||||
								<reference key="NSColor" ref="112253361"/>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="NSColor" key="NSTextColor" id="1057393278">
 | 
			
		||||
								<int key="NSColorSpace">6</int>
 | 
			
		||||
								<string key="NSCatalogName">System</string>
 | 
			
		||||
								<string key="NSColorName">textColor</string>
 | 
			
		||||
								<reference key="NSColor" ref="342700193"/>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="NSArray" key="NSAllowedInputLocales">
 | 
			
		||||
								<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
								<string>NSAllRomanInputSourcesLocaleIdentifier</string>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSTextField" id="920985464">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<string key="NSFrame">{{90, 162}, {227, 22}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="850820204"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSTextFieldCell" key="NSCell" id="337856829">
 | 
			
		||||
							<int key="NSCellFlags">-1804468671</int>
 | 
			
		||||
							<int key="NSCellFlags2">272630784</int>
 | 
			
		||||
							<string key="NSContents"/>
 | 
			
		||||
							<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
							<reference key="NSControlView" ref="920985464"/>
 | 
			
		||||
							<bool key="NSDrawsBackground">YES</bool>
 | 
			
		||||
							<reference key="NSBackgroundColor" ref="817216621"/>
 | 
			
		||||
							<reference key="NSTextColor" ref="1057393278"/>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSTextField" id="850820204">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<string key="NSFrame">{{17, 139}, {68, 17}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="1968599"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSTextFieldCell" key="NSCell" id="931655839">
 | 
			
		||||
							<int key="NSCellFlags">68288064</int>
 | 
			
		||||
							<int key="NSCellFlags2">71304192</int>
 | 
			
		||||
							<string key="NSContents">Lösenord:</string>
 | 
			
		||||
							<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
							<reference key="NSControlView" ref="850820204"/>
 | 
			
		||||
							<object class="NSColor" key="NSBackgroundColor" id="268730744">
 | 
			
		||||
								<int key="NSColorSpace">6</int>
 | 
			
		||||
								<string key="NSCatalogName">System</string>
 | 
			
		||||
								<string key="NSColorName">controlColor</string>
 | 
			
		||||
								<reference key="NSColor" ref="859429791"/>
 | 
			
		||||
							</object>
 | 
			
		||||
							<reference key="NSTextColor" ref="888636459"/>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSTextField" id="107981744">
 | 
			
		||||
						<reference key="NSNextResponder" ref="1005"/>
 | 
			
		||||
						<int key="NSvFlags">268</int>
 | 
			
		||||
						<string key="NSFrame">{{17, 164}, {68, 17}}</string>
 | 
			
		||||
						<reference key="NSSuperview" ref="1005"/>
 | 
			
		||||
						<reference key="NSWindow"/>
 | 
			
		||||
						<reference key="NSNextKeyView" ref="920985464"/>
 | 
			
		||||
						<bool key="NSEnabled">YES</bool>
 | 
			
		||||
						<object class="NSTextFieldCell" key="NSCell" id="149273787">
 | 
			
		||||
							<int key="NSCellFlags">68288064</int>
 | 
			
		||||
							<int key="NSCellFlags2">71304192</int>
 | 
			
		||||
							<string key="NSContents">Epost:</string>
 | 
			
		||||
							<reference key="NSSupport" ref="902206146"/>
 | 
			
		||||
							<reference key="NSControlView" ref="107981744"/>
 | 
			
		||||
							<reference key="NSBackgroundColor" ref="268730744"/>
 | 
			
		||||
							<reference key="NSTextColor" ref="888636459"/>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
				<string key="NSFrameSize">{337, 204}</string>
 | 
			
		||||
				<reference key="NSSuperview"/>
 | 
			
		||||
				<reference key="NSWindow"/>
 | 
			
		||||
				<reference key="NSNextKeyView" ref="107981744"/>
 | 
			
		||||
				<string key="NSClassName">NSView</string>
 | 
			
		||||
			</object>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBObjectContainer" key="IBDocument.Objects">
 | 
			
		||||
			<object class="NSMutableArray" key="connectionRecords">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">view</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">2</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">nextKeyView</string>
 | 
			
		||||
						<reference key="source" ref="920985464"/>
 | 
			
		||||
						<reference key="destination" ref="1968599"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">11</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBActionConnection" key="connection">
 | 
			
		||||
						<string key="label">login:</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="166222988"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">32</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">emailField</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="920985464"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">33</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">passwordField</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="1968599"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">34</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">dataSource</string>
 | 
			
		||||
						<reference key="source" ref="472926426"/>
 | 
			
		||||
						<reference key="destination" ref="1001"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">35</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">delegate</string>
 | 
			
		||||
						<reference key="source" ref="472926426"/>
 | 
			
		||||
						<reference key="destination" ref="1001"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">36</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">publicOutline</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="472926426"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">37</int>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="IBConnectionRecord">
 | 
			
		||||
					<object class="IBOutletConnection" key="connection">
 | 
			
		||||
						<string key="label">loginButton</string>
 | 
			
		||||
						<reference key="source" ref="1001"/>
 | 
			
		||||
						<reference key="destination" ref="166222988"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<int key="connectionID">38</int>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="IBMutableOrderedSet" key="objectRecords">
 | 
			
		||||
				<object class="NSArray" key="orderedObjects">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">0</int>
 | 
			
		||||
						<reference key="object" ref="0"/>
 | 
			
		||||
						<reference key="children" ref="1000"/>
 | 
			
		||||
						<nil key="parent"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-2</int>
 | 
			
		||||
						<reference key="object" ref="1001"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">File's Owner</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-1</int>
 | 
			
		||||
						<reference key="object" ref="1003"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">First Responder</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">-3</int>
 | 
			
		||||
						<reference key="object" ref="1004"/>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
						<string key="objectName">Application</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">1</int>
 | 
			
		||||
						<reference key="object" ref="1005"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="107981744"/>
 | 
			
		||||
							<reference ref="850820204"/>
 | 
			
		||||
							<reference ref="920985464"/>
 | 
			
		||||
							<reference ref="1968599"/>
 | 
			
		||||
							<reference ref="512917876"/>
 | 
			
		||||
							<reference ref="159969733"/>
 | 
			
		||||
							<reference ref="166222988"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="0"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">3</int>
 | 
			
		||||
						<reference key="object" ref="107981744"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="149273787"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">4</int>
 | 
			
		||||
						<reference key="object" ref="850820204"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="931655839"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">5</int>
 | 
			
		||||
						<reference key="object" ref="920985464"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="337856829"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">6</int>
 | 
			
		||||
						<reference key="object" ref="1968599"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="106272887"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">7</int>
 | 
			
		||||
						<reference key="object" ref="106272887"/>
 | 
			
		||||
						<reference key="parent" ref="1968599"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">8</int>
 | 
			
		||||
						<reference key="object" ref="337856829"/>
 | 
			
		||||
						<reference key="parent" ref="920985464"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">9</int>
 | 
			
		||||
						<reference key="object" ref="931655839"/>
 | 
			
		||||
						<reference key="parent" ref="850820204"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">10</int>
 | 
			
		||||
						<reference key="object" ref="149273787"/>
 | 
			
		||||
						<reference key="parent" ref="107981744"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">12</int>
 | 
			
		||||
						<reference key="object" ref="512917876"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="467645476"/>
 | 
			
		||||
							<reference ref="643577797"/>
 | 
			
		||||
							<reference ref="472926426"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">13</int>
 | 
			
		||||
						<reference key="object" ref="467645476"/>
 | 
			
		||||
						<reference key="parent" ref="512917876"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">14</int>
 | 
			
		||||
						<reference key="object" ref="643577797"/>
 | 
			
		||||
						<reference key="parent" ref="512917876"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">15</int>
 | 
			
		||||
						<reference key="object" ref="472926426"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="196057634"/>
 | 
			
		||||
							<reference ref="24135004"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="512917876"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">17</int>
 | 
			
		||||
						<reference key="object" ref="196057634"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="850771707"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="472926426"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">18</int>
 | 
			
		||||
						<reference key="object" ref="24135004"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="1048517996"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="472926426"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">20</int>
 | 
			
		||||
						<reference key="object" ref="850771707"/>
 | 
			
		||||
						<reference key="parent" ref="196057634"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">21</int>
 | 
			
		||||
						<reference key="object" ref="1048517996"/>
 | 
			
		||||
						<reference key="parent" ref="24135004"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">22</int>
 | 
			
		||||
						<reference key="object" ref="166222988"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="549737638"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">23</int>
 | 
			
		||||
						<reference key="object" ref="549737638"/>
 | 
			
		||||
						<reference key="parent" ref="166222988"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">30</int>
 | 
			
		||||
						<reference key="object" ref="159969733"/>
 | 
			
		||||
						<object class="NSMutableArray" key="children">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<reference ref="719969108"/>
 | 
			
		||||
						</object>
 | 
			
		||||
						<reference key="parent" ref="1005"/>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBObjectRecord">
 | 
			
		||||
						<int key="objectID">31</int>
 | 
			
		||||
						<reference key="object" ref="719969108"/>
 | 
			
		||||
						<reference key="parent" ref="159969733"/>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSMutableDictionary" key="flattenedProperties">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<string>1.IBEditorWindowLastContentRect</string>
 | 
			
		||||
					<string>1.IBPluginDependency</string>
 | 
			
		||||
					<string>1.WindowOrigin</string>
 | 
			
		||||
					<string>1.editorWindowContentRectSynchronizationRect</string>
 | 
			
		||||
					<string>10.IBPluginDependency</string>
 | 
			
		||||
					<string>12.IBPluginDependency</string>
 | 
			
		||||
					<string>12.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>13.IBPluginDependency</string>
 | 
			
		||||
					<string>14.IBPluginDependency</string>
 | 
			
		||||
					<string>15.IBPluginDependency</string>
 | 
			
		||||
					<string>17.IBPluginDependency</string>
 | 
			
		||||
					<string>18.IBPluginDependency</string>
 | 
			
		||||
					<string>20.IBPluginDependency</string>
 | 
			
		||||
					<string>21.IBPluginDependency</string>
 | 
			
		||||
					<string>22.IBPluginDependency</string>
 | 
			
		||||
					<string>22.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>23.IBPluginDependency</string>
 | 
			
		||||
					<string>3.IBPluginDependency</string>
 | 
			
		||||
					<string>3.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>30.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>4.IBPluginDependency</string>
 | 
			
		||||
					<string>4.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>5.IBPluginDependency</string>
 | 
			
		||||
					<string>5.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>6.IBPluginDependency</string>
 | 
			
		||||
					<string>6.IBViewBoundsToFrameTransform</string>
 | 
			
		||||
					<string>7.IBPluginDependency</string>
 | 
			
		||||
					<string>8.IBPluginDependency</string>
 | 
			
		||||
					<string>9.IBPluginDependency</string>
 | 
			
		||||
				</object>
 | 
			
		||||
				<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
					<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
					<string>{{337, 450}, {337, 204}}</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>{628, 654}</string>
 | 
			
		||||
					<string>{{217, 442}, {480, 272}}</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAwxQAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAAC/gAAAwrIAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAABCsAAAwxoAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">AUIAAABDRQAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAABCsAAAwwEAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAABDJgAAwx0AAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<object class="NSAffineTransform">
 | 
			
		||||
						<bytes key="NSTransformStruct">P4AAAL+AAABDJgAAwwQAAA</bytes>
 | 
			
		||||
					</object>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
					<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSMutableDictionary" key="unlocalizedProperties">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<reference key="dict.sortedKeys" ref="0"/>
 | 
			
		||||
				<reference key="dict.values" ref="0"/>
 | 
			
		||||
			</object>
 | 
			
		||||
			<nil key="activeLocalization"/>
 | 
			
		||||
			<object class="NSMutableDictionary" key="localizations">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<reference key="dict.sortedKeys" ref="0"/>
 | 
			
		||||
				<reference key="dict.values" ref="0"/>
 | 
			
		||||
			</object>
 | 
			
		||||
			<nil key="sourceID"/>
 | 
			
		||||
			<int key="maxID">38</int>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="IBClassDescriber" key="IBDocument.Classes">
 | 
			
		||||
			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<object class="IBPartialClassDescription">
 | 
			
		||||
					<string key="className">MGMDropboxPlugIn</string>
 | 
			
		||||
					<string key="superclassName">NSObject</string>
 | 
			
		||||
					<object class="NSMutableDictionary" key="actions">
 | 
			
		||||
						<string key="NS.key.0">login:</string>
 | 
			
		||||
						<string key="NS.object.0">id</string>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSMutableDictionary" key="actionInfosByName">
 | 
			
		||||
						<string key="NS.key.0">login:</string>
 | 
			
		||||
						<object class="IBActionInfo" key="NS.object.0">
 | 
			
		||||
							<string key="name">login:</string>
 | 
			
		||||
							<string key="candidateClassName">id</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSMutableDictionary" key="outlets">
 | 
			
		||||
						<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
						<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>emailField</string>
 | 
			
		||||
							<string>loginButton</string>
 | 
			
		||||
							<string>passwordField</string>
 | 
			
		||||
							<string>publicOutline</string>
 | 
			
		||||
							<string>view</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>NSTextField</string>
 | 
			
		||||
							<string>NSButton</string>
 | 
			
		||||
							<string>NSTextField</string>
 | 
			
		||||
							<string>NSOutlineView</string>
 | 
			
		||||
							<string>NSView</string>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
 | 
			
		||||
						<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
						<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<string>emailField</string>
 | 
			
		||||
							<string>loginButton</string>
 | 
			
		||||
							<string>passwordField</string>
 | 
			
		||||
							<string>publicOutline</string>
 | 
			
		||||
							<string>view</string>
 | 
			
		||||
						</object>
 | 
			
		||||
						<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
							<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<string key="name">emailField</string>
 | 
			
		||||
								<string key="candidateClassName">NSTextField</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<string key="name">loginButton</string>
 | 
			
		||||
								<string key="candidateClassName">NSButton</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<string key="name">passwordField</string>
 | 
			
		||||
								<string key="candidateClassName">NSTextField</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<string key="name">publicOutline</string>
 | 
			
		||||
								<string key="candidateClassName">NSOutlineView</string>
 | 
			
		||||
							</object>
 | 
			
		||||
							<object class="IBToOneOutletInfo">
 | 
			
		||||
								<string key="name">view</string>
 | 
			
		||||
								<string key="candidateClassName">NSView</string>
 | 
			
		||||
							</object>
 | 
			
		||||
						</object>
 | 
			
		||||
					</object>
 | 
			
		||||
					<object class="IBClassDescriptionSource" key="sourceIdentifier">
 | 
			
		||||
						<string key="majorKey">IBProjectSource</string>
 | 
			
		||||
						<string key="minorKey">./Classes/MGMDropboxPlugIn.h</string>
 | 
			
		||||
					</object>
 | 
			
		||||
				</object>
 | 
			
		||||
			</object>
 | 
			
		||||
		</object>
 | 
			
		||||
		<int key="IBDocument.localizationMode">0</int>
 | 
			
		||||
		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
 | 
			
		||||
			<integer value="1050" key="NS.object.0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
 | 
			
		||||
			<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
 | 
			
		||||
			<integer value="3000" key="NS.object.0"/>
 | 
			
		||||
		</object>
 | 
			
		||||
		<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
 | 
			
		||||
		<int key="IBDocument.defaultPropertyAccessControl">3</int>
 | 
			
		||||
		<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
 | 
			
		||||
			<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
			<object class="NSArray" key="dict.sortedKeys">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<string>NSSwitch</string>
 | 
			
		||||
				<string>db_logo</string>
 | 
			
		||||
			</object>
 | 
			
		||||
			<object class="NSMutableArray" key="dict.values">
 | 
			
		||||
				<bool key="EncodedWithXMLCoder">YES</bool>
 | 
			
		||||
				<string>{15, 15}</string>
 | 
			
		||||
				<string>{116, 32}</string>
 | 
			
		||||
			</object>
 | 
			
		||||
		</object>
 | 
			
		||||
	</data>
 | 
			
		||||
</archive>
 | 
			
		||||
							
								
								
									
										202
									
								
								index.php
									
									
									
									
									
								
							
							
						
						@ -7,8 +7,86 @@
 | 
			
		||||
//  Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
class shortID {
 | 
			
		||||
	var $lowerCase = false;
 | 
			
		||||
	
 | 
			
		||||
	var $check = array(3, 20);
 | 
			
		||||
	var $charactersAllCase = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@*-_=+,.;'|";
 | 
			
		||||
	var $charactersLowerCase = "abcdefghijklmnopqrstuvwxyz1234567890!@*-_=+,.;'|";
 | 
			
		||||
	var $alphabet = array();
 | 
			
		||||
	var $base = 0;
 | 
			
		||||
	
 | 
			
		||||
	function __construct($lowerCase = false) {
 | 
			
		||||
		$this->lowerCase = $lowerCase;
 | 
			
		||||
		$this->alphabet = str_split(($this->lowerCase ? $this->charactersLowerCase : $this->charactersAllCase));
 | 
			
		||||
		$this->base = count($this->alphabet);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	function shuffleAlphabet($lowerCase = false) {
 | 
			
		||||
		$alphabet = str_split(($lowerCase ? $this->charactersLowerCase : $this->charactersAllCase));
 | 
			
		||||
		$count = count($alphabet);
 | 
			
		||||
		for ($i=0; $i<60; $i++) {
 | 
			
		||||
			for ($c=0; $c<$count; $c++) {
 | 
			
		||||
				$newPos = rand(0, $count);
 | 
			
		||||
				$tmp = $alphabet[$c];
 | 
			
		||||
				$alphabet[$c] = $alphabet[$newPos];
 | 
			
		||||
				$alphabet[$newPos] = $tmp;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return implode($alphabet);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	function encode($id) {
 | 
			
		||||
		if ($id<=0) {
 | 
			
		||||
			return "";
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		$checkString = "";
 | 
			
		||||
		foreach ($this->check as $check) {
 | 
			
		||||
			$checkString .= $this->alphabet[$id%$check];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		$encoded = "";
 | 
			
		||||
		while ($id>0) {
 | 
			
		||||
			$encoded = $this->alphabet[$id%$this->base].$encoded;
 | 
			
		||||
			$id = (int)($id/$this->base);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return $checkString.$encoded;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	function decode($encoded) {
 | 
			
		||||
		$checkSize = count($this->check);
 | 
			
		||||
		if (strlen($encoded)<=$checkSize) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		$id = 0;
 | 
			
		||||
		
 | 
			
		||||
		$checkString = substr($encoded, 0, $checkSize);
 | 
			
		||||
		
 | 
			
		||||
		$values = str_split(substr($encoded, $checkSize));
 | 
			
		||||
		
 | 
			
		||||
		foreach ($values as $value) {
 | 
			
		||||
			$id = ($id*$this->base)+array_search($value, $this->alphabet);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		$newCheckString = "";
 | 
			
		||||
		foreach ($this->check as $check) {
 | 
			
		||||
			$newCheckString .= $this->alphabet[$id%$check];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ($newCheckString!=$checkString) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return $id;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
header("Content-Type: application/json");
 | 
			
		||||
 | 
			
		||||
$_CS = array();
 | 
			
		||||
$_CS['version'] = "0.2";
 | 
			
		||||
$_CS['version'] = "0.4";
 | 
			
		||||
$_CS['time'] = time();
 | 
			
		||||
 | 
			
		||||
// You are expected to understand a little PHP to use this file.
 | 
			
		||||
@ -67,111 +145,69 @@ if (!empty($_COOKIE["{$_CS['cookiePrefix']}user"])) {
 | 
			
		||||
		$_CS['loggedIn'] = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$response = array();
 | 
			
		||||
$response["version"] = $_CS['version'];
 | 
			
		||||
 | 
			
		||||
if (isset($_REQUEST['login'])) {
 | 
			
		||||
	$password = $_CS['users'][strtolower($_REQUEST['user'])];
 | 
			
		||||
	if ($password==md5($_REQUEST['password'])) {
 | 
			
		||||
		setcookie("{$_CS['cookiePrefix']}user", strtolower($_REQUEST['user']), $_CS['time']+31536000/* 1 year */, $_COOKIE['cookiePath'], $_COOKIE['cookieDomain']);
 | 
			
		||||
		setcookie("{$_CS['cookiePrefix']}password", md5($_CS['salt'].md5($_REQUEST['password'])), $_CS['time']+31536000/* 1 year */, $_COOKIE['cookiePath'], $_COOKIE['cookieDomain']);
 | 
			
		||||
		echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
		?>
 | 
			
		||||
		<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
		<plist version="1.0">
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>successful</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
			<key>loggedIn</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
		</dict>
 | 
			
		||||
		</plist>
 | 
			
		||||
		<?
 | 
			
		||||
		$response["successful"] = true;
 | 
			
		||||
		$response["loggedIn"] = true;
 | 
			
		||||
		echo json_encode($response);
 | 
			
		||||
	} else {
 | 
			
		||||
		echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
		?>
 | 
			
		||||
		<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
		<plist version="1.0">
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>successful</key>
 | 
			
		||||
			<false/>
 | 
			
		||||
			<key>error</key>
 | 
			
		||||
			<string>Incorrect login details.</string>
 | 
			
		||||
			<key>loggedIn</key>
 | 
			
		||||
			<false/>
 | 
			
		||||
		</dict>
 | 
			
		||||
		</plist>
 | 
			
		||||
		<?
 | 
			
		||||
		$response["successful"] = false;
 | 
			
		||||
		$response["loggedIn"] = false;
 | 
			
		||||
		$response["error"] = "Invalid login details.";
 | 
			
		||||
		echo json_encode($response);
 | 
			
		||||
	}
 | 
			
		||||
	exit();
 | 
			
		||||
}
 | 
			
		||||
if ($_CS['loggedIn']) {
 | 
			
		||||
	$response["loggedIn"] = true;
 | 
			
		||||
	if (isset($_REQUEST['upload'])) {
 | 
			
		||||
		$file = $_FILES[$_REQUEST['upload']];
 | 
			
		||||
		$fileNameArr = explode(".", basename($file['name']));
 | 
			
		||||
		$fileEtc = strtolower(end($fileNameArr));
 | 
			
		||||
		$uploadName = basename($file['name']);
 | 
			
		||||
		$currentID = 0;
 | 
			
		||||
		$idFile = "./index.txt";
 | 
			
		||||
		if (file_exists($idFile)) {
 | 
			
		||||
			$fp = fopen($idFile, "r");
 | 
			
		||||
			$currentID = intval(fread($fp, 10));//Max size is 2147483647 for 32bit int.
 | 
			
		||||
			fclose($fp);
 | 
			
		||||
		}
 | 
			
		||||
		if ($currentID!=2147483647) {//Max id reached.
 | 
			
		||||
			$currentID++;
 | 
			
		||||
			$shortID = new shortID();
 | 
			
		||||
			$uploadName = $shortID->encode($currentID).".".$fileEtc;
 | 
			
		||||
			$fp = fopen($idFile, "w+");
 | 
			
		||||
			fwrite($fp, $currentID);
 | 
			
		||||
			fclose($fp);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (file_exists("./{$uploadName}"))
 | 
			
		||||
			unlink("./{$uploadName}");
 | 
			
		||||
		if (move_uploaded_file($file['tmp_name'], "./{$uploadName}")) {
 | 
			
		||||
			chmod("./{$uploadName}", 0666);
 | 
			
		||||
			echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
			?>
 | 
			
		||||
			<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
			<plist version="1.0">
 | 
			
		||||
			<dict>
 | 
			
		||||
				<key>successful</key>
 | 
			
		||||
				<true/>
 | 
			
		||||
				<key>url</key>
 | 
			
		||||
				<string><?=generateURL(rawurlencode($uploadName))?></string>
 | 
			
		||||
				<key>loggedIn</key>
 | 
			
		||||
				<true/>
 | 
			
		||||
			</dict>
 | 
			
		||||
			</plist>
 | 
			
		||||
			<?
 | 
			
		||||
			$response["successful"] = true;
 | 
			
		||||
			$response["url"] = generateURL(rawurlencode($uploadName));
 | 
			
		||||
			echo json_encode($response);
 | 
			
		||||
		} else {
 | 
			
		||||
			echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
			?>
 | 
			
		||||
			<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
			<plist version="1.0">
 | 
			
		||||
			<dict>
 | 
			
		||||
				<key>successful</key>
 | 
			
		||||
				<false/>
 | 
			
		||||
				<key>error</key>
 | 
			
		||||
				<string>Incorrect access.</string>
 | 
			
		||||
				<key>loggedIn</key>
 | 
			
		||||
				<true/>
 | 
			
		||||
			</dict>
 | 
			
		||||
			</plist>
 | 
			
		||||
			<?
 | 
			
		||||
			$response["successful"] = false;
 | 
			
		||||
			$response["error"] = "Incorrect access.";
 | 
			
		||||
			echo json_encode($response);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
		?>
 | 
			
		||||
		<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
		<plist version="1.0">
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>successful</key>
 | 
			
		||||
			<false/>
 | 
			
		||||
			<key>error</key>
 | 
			
		||||
			<string>Incorrect access.</string>
 | 
			
		||||
			<key>loggedIn</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
		</dict>
 | 
			
		||||
		</plist>
 | 
			
		||||
		<?
 | 
			
		||||
		$response["successful"] = false;
 | 
			
		||||
		$response["error"] = "Invalid request.";
 | 
			
		||||
		echo json_encode($response);
 | 
			
		||||
	}
 | 
			
		||||
} else {
 | 
			
		||||
	echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
 | 
			
		||||
	?>
 | 
			
		||||
	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
			
		||||
	<plist version="1.0">
 | 
			
		||||
	<dict>
 | 
			
		||||
		<key>successful</key>
 | 
			
		||||
		<false/>
 | 
			
		||||
		<key>error</key>
 | 
			
		||||
		<string>You need to login.</string>
 | 
			
		||||
		<key>loggedIn</key>
 | 
			
		||||
		<false/>
 | 
			
		||||
	</dict>
 | 
			
		||||
	</plist>
 | 
			
		||||
	<?
 | 
			
		||||
	$response["successful"] = false;
 | 
			
		||||
	$response["loggedIn"] = false;
 | 
			
		||||
	$response["error"] = "You need to login.";
 | 
			
		||||
	echo json_encode($response);
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||