diff --git a/VVBasics/VVBasics.h b/VVBasics/VVBasics.h index 05638d0..96c1827 100644 --- a/VVBasics/VVBasics.h +++ b/VVBasics/VVBasics.h @@ -8,6 +8,7 @@ #import "MutLockDict.h" #import "MutNRLockArray.h" #import "NamedMutLockArray.h" +#import "VVCURLDL.h" /* the following stuff is for doxygen diff --git a/VVBasics/src/VVCURLDL.h b/VVBasics/src/VVCURLDL.h new file mode 100644 index 0000000..662ae0d --- /dev/null +++ b/VVBasics/src/VVCURLDL.h @@ -0,0 +1,48 @@ +// +// VVCURLDL.h +// VVOpenSource +// +// Created by bagheera on 9/17/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import + + + + +@protocol VVCURLDLDelegate +- (void) dlFinished:(id)h; +@end + + + + +@interface VVCURLDL : NSObject { + NSString *urlString; + CURL *curlHandle; + NSMutableData *postData; + NSMutableData *responseData; + + BOOL returnOnMain; +} + ++ (id) createWithAddress:(NSString *)a; +- (id) initWithAddress:(NSString *)a; + +- (void) perform; +- (void) performAsync:(BOOL)as withDelegate:(id )d; +- (void) _performAsyncWithDelegate:(id )d; +- (void) _performWithDelegate:(id )d; + +- (void) appendDataToPost:(NSData *)d; +- (void) appendStringToPost:(NSString *)s; + +- (void) writePtr:(void *)ptr size:(size_t)s; + +@property (assign,readonly) BOOL returnOnMain; + +@end + +size_t vvcurlWriteFunction(void *ptr, size_t size, size_t nmemb, void *stream); diff --git a/VVBasics/src/VVCURLDL.m b/VVBasics/src/VVCURLDL.m new file mode 100644 index 0000000..642ed1a --- /dev/null +++ b/VVBasics/src/VVCURLDL.m @@ -0,0 +1,149 @@ +// +// VVCURLDL.m +// VVOpenSource +// +// Created by bagheera on 9/17/09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "VVCURLDL.h" + + + + +@implementation VVCURLDL + + ++ (id) createWithAddress:(NSString *)a { + VVCURLDL *returnMe = [[VVCURLDL alloc] initWithAddress:a]; + if (returnMe == nil) + return nil; + return [returnMe autorelease]; +} +- (id) initWithAddress:(NSString *)a { + if (a==nil) + goto BAIL; + if (self = [super init]) { + urlString = [a retain]; + curlHandle = nil; + postData = nil; + responseData = nil; + returnOnMain = NO; + return self; + } + BAIL: + [self release]; + return nil; +} +- (void) dealloc { + if (urlString != nil) { + [urlString release]; + urlString = nil; + } + if (postData != nil) { + [postData release]; + postData = nil; + } + if (responseData != nil) { + [responseData release]; + responseData = nil; + } + [super dealloc]; +} + +- (void) perform { + [self performAsync:NO withDelegate:nil]; +} +- (void) performAsync:(BOOL)as withDelegate:(id )d { + // if i'm performing asynchronously, spawn a thread (make an autorelease pool!) and go + if (as) + [NSThread detachNewThreadSelector:@selector(_performAsyncWithDelegate:) toTarget:self withObject:d]; + // else just go + else + [self _performWithDelegate:d]; +} +// DO NOT CALL THIS METHOD DIRECTLY +- (void) _performAsyncWithDelegate:(id )d { + // make a pool + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + // perform the download + [self _performWithDelegate:d]; + // release the pool + [pool release]; +} +// DO NOT CALL THIS METHOD DIRECTLY +- (void) _performWithDelegate:(id )d { + CURLcode err; + + curlHandle = curl_easy_init(); + if (curlHandle) { + // set the URL + curl_easy_setopt(curlHandle,CURLOPT_URL,[urlString UTF8String]); + // if there's post data, set that up + if (postData != nil) { + curl_easy_setopt(curlHandle,CURLOPT_POSTFIELDS,[postData bytes]); + } + // set up a write function so libcurl can send me data it receives + curl_easy_setopt(curlHandle,CURLOPT_WRITEFUNCTION,vvcurlWriteFunction); + // i'm going to pass a pointer to myself as the file stream, so i can get back into objective-c + curl_easy_setopt(curlHandle,CURLOPT_WRITEDATA,self); + // perform the transfer + err = curl_easy_perform(curlHandle); + if (err) { + NSLog(@"\terr %ld at curl_easy_perform",err); + + } + else { + /* + if (responseData != nil) { + NSString *tmpString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease]; + NSLog(@"%@",tmpString); + } + */ + } + // clean up after the transfer + curl_easy_cleanup(curlHandle); + curlHandle = nil; + } + else + NSLog(@"\terror at curl_easy_init() in %s",__func__); + + // if there's a delegate, tell the delegate that shit's done + if ((d!=nil)&&([(id)d conformsToProtocol:@protocol(VVCURLDLDelegate)])) { + if (returnOnMain) + [(id)d performSelectorOnMainThread:@selector(dlFinished:) withObject:self waitUntilDone:YES]; + [(id)d dlFinished:self]; + } +} + +- (void) appendDataToPost:(NSData *)d { + if (d == nil) + return; + if (postData == nil) + postData = [[NSMutableData dataWithCapacity:0] retain]; + [postData appendData:d]; +} +- (void) appendStringToPost:(NSString *)s { + if (s == nil) + return; + [self appendDataToPost:[s dataUsingEncoding:NSUTF8StringEncoding]]; +} + +- (void) writePtr:(void *)ptr size:(size_t)s { + //NSLog(@"%s",__func__); + if (responseData == nil) + responseData = [[NSMutableData dataWithCapacity:0] retain]; + [responseData appendBytes:ptr length:s]; +} + +@synthesize returnOnMain; + + +@end + + +size_t vvcurlWriteFunction(void *ptr, size_t size, size_t nmemb, void *stream) { + if (stream != nil) + [(VVCURLDL *)stream writePtr:ptr size:size*nmemb]; + return size*nmemb; +} \ No newline at end of file diff --git a/VVOpenSource.xcodeproj/project.pbxproj b/VVOpenSource.xcodeproj/project.pbxproj index 289ab6b..276f33f 100644 --- a/VVOpenSource.xcodeproj/project.pbxproj +++ b/VVOpenSource.xcodeproj/project.pbxproj @@ -250,6 +250,8 @@ 96BF10B0100E95330079A2E6 /* VVOSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 96BF10AD100E95330079A2E6 /* VVOSC.h */; }; 96BF10B1100E95330079A2E6 /* VVOSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 96BF10AD100E95330079A2E6 /* VVOSC.h */; }; 96C2F2141017815F004E19B0 /* OSCConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 96C2F2131017815F004E19B0 /* OSCConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 96ED419910628A5500D8373F /* VVCURLDL.h in Headers */ = {isa = PBXBuildFile; fileRef = 96ED419710628A5500D8373F /* VVCURLDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 96ED419A10628A5500D8373F /* VVCURLDL.m in Sources */ = {isa = PBXBuildFile; fileRef = 96ED419810628A5500D8373F /* VVCURLDL.m */; }; BD9F6A0C10191358004D8CD9 /* FreeFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = BD9F6A0A10191358004D8CD9 /* FreeFrame.h */; }; BD9F6A88101921FD004D8CD9 /* FFGL.h in Headers */ = {isa = PBXBuildFile; fileRef = BD9F6A87101921FD004D8CD9 /* FFGL.h */; }; /* End PBXBuildFile section */ @@ -574,6 +576,8 @@ 96BF10C8100E98760079A2E6 /* assembleIPhoneSimSDK.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = assembleIPhoneSimSDK.sh; path = scripts/assembleIPhoneSimSDK.sh; sourceTree = ""; }; 96BF10C9100E98930079A2E6 /* assembleMacSDK.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = assembleMacSDK.sh; path = scripts/assembleMacSDK.sh; sourceTree = ""; }; 96C2F2131017815F004E19B0 /* OSCConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSCConstants.h; path = VVOSC/FrameworkSrc/OSCConstants.h; sourceTree = ""; }; + 96ED419710628A5500D8373F /* VVCURLDL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VVCURLDL.h; path = VVBasics/src/VVCURLDL.h; sourceTree = ""; }; + 96ED419810628A5500D8373F /* VVCURLDL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VVCURLDL.m; path = VVBasics/src/VVCURLDL.m; sourceTree = ""; }; BD9F6A0A10191358004D8CD9 /* FreeFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FreeFrame.h; path = VVFFGL/FrameworkSrc/FreeFrame.h; sourceTree = ""; }; BD9F6A87101921FD004D8CD9 /* FFGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FFGL.h; path = VVFFGL/FrameworkSrc/FFGL.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -800,6 +804,8 @@ 961EA953100E8834007E6C25 /* NamedMutLockArray.m */, 961EA956100E8834007E6C25 /* MutNRLockArray.h */, 961EA955100E8834007E6C25 /* MutNRLockArray.m */, + 96ED419710628A5500D8373F /* VVCURLDL.h */, + 96ED419810628A5500D8373F /* VVCURLDL.m */, ); name = "VVBasics framework"; sourceTree = ""; @@ -927,6 +933,7 @@ 961EA964100E8834007E6C25 /* NamedMutLockArray.h in Headers */, 961EA966100E8834007E6C25 /* MutNRLockArray.h in Headers */, 96BF10A9100E95200079A2E6 /* VVBasics.h in Headers */, + 96ED419910628A5500D8373F /* VVCURLDL.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1516,6 +1523,7 @@ 961EA961100E8834007E6C25 /* ObjectHolder.m in Sources */, 961EA963100E8834007E6C25 /* NamedMutLockArray.m in Sources */, 961EA965100E8834007E6C25 /* MutNRLockArray.m in Sources */, + 96ED419A10628A5500D8373F /* VVCURLDL.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2000,6 +2008,7 @@ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; INFOPLIST_FILE = "VVBasics-Info.plist"; INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = "-lcurl"; PRODUCT_NAME = VVBasics; }; name = Debug; @@ -2021,6 +2030,7 @@ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; INFOPLIST_FILE = "VVBasics-Info.plist"; INSTALL_PATH = "@executable_path/../Frameworks"; + OTHER_LDFLAGS = "-lcurl"; PRODUCT_NAME = VVBasics; ZERO_LINK = NO; };