rejigger things to do callbacks and end-of-stream read properly

This commit is contained in:
Max Lansing 2012-07-19 22:23:38 -07:00
parent d434de241f
commit c7f6fb09bf
2 changed files with 383 additions and 387 deletions

View file

@ -503,7 +503,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
__block AFStreamingMultipartFormData * formData = [[[AFStreamingMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
// __block AFMultipartFormData *formData = [[[AFMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
// __block AFMultipartFormData *formData = [[[AFMultipartFormData alloc] initWithURLRequest:request stringEncoding:self.stringEncoding] autorelease];
for (AFQueryStringComponent *component in AFQueryStringComponentsFromKeyAndValue(nil, parameters)) {
NSData *data = nil;
@ -813,7 +813,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
stringEncoding = NSUTF8StringEncoding;
streamStatus = NSStreamStatusNotOpen;
[self resetCursors];
[self setDelegate:self];
// [self setDelegate:self];
return self;
}
@ -938,7 +938,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
}
-(NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)len offsetCursor:(NSUInteger*)offsetCursorPtr {
NSUInteger bytesAvailable = [data length] - *offsetCursorPtr;
NSInteger bytesAvailable = [data length] - *offsetCursorPtr;
if (len > bytesAvailable) {
[data getBytes:buffer range:NSMakeRange(*offsetCursorPtr, bytesAvailable)];
*offsetCursorPtr += bytesAvailable;
@ -979,7 +979,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
}
-(NSUInteger)totalElements {
return [formDatas count] + [fileURLs count];
return [formDatas count] + [fileURLs count] + 1; //one extra for final boundary
}
-(NSData *)finalBoundaryData {
@ -1036,10 +1036,14 @@ static inline NSString * AFMultipartFormFinalBoundary() {
#pragma mark - NSInputStream subclass overrides
-(NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len {
if ([self streamStatus] == NSStreamStatusClosed) {
return 0;
}
assert ([self streamStatus] == NSStreamStatusOpen);
NSUInteger bytesRead = 0;
NSUInteger readFileCursor = (readElementCursor - [formNames count]);
NSInteger bytesRead = 0;
NSInteger readFileCursor = (readElementCursor - [formNames count]);
if (readElementCursor < [formNames count]) {
//reading from formDatas
@ -1056,7 +1060,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
[self nextElement];
}
}
else if (readElementCursor >= [formNames count] && readFileCursor < [fileNames count]) {
else if (readFileCursor >= 0 && readFileCursor < [fileNames count]) {
//reading from files
NSString * currentFileName = [fileNames objectAtIndex:readFileCursor];
NSURL * currentFileURL = [fileURLs objectForKey:currentFileName];
@ -1069,7 +1073,7 @@ static inline NSString * AFMultipartFormFinalBoundary() {
} else {
if (!currentFileStream) {
currentFileStream = [[NSInputStream inputStreamWithURL:currentFileURL] retain];
currentFileStream.delegate = self;
// currentFileStream.delegate = self;
[currentFileStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[currentFileStream open];
}
@ -1081,44 +1085,37 @@ static inline NSString * AFMultipartFormFinalBoundary() {
}
}
}
else {
else if (readElementCursor < [self totalElements]) {
//add final boundary
bytesRead = [self readData:[self finalBoundaryData] intoBuffer:buffer maxLength:len offsetCursor:&readOffsetCursor];
if (readOffsetCursor == [[self finalBoundaryData] length]) {
[self nextElement];
}
}
if (bytesRead < len && readElementCursor <= [self totalElements]) {
//recurse to fill out the buffer, this is critical if the above read operations produce a zero length buffer for some reason (empty form data, end of file) because returning zero from this method will result in the stream being closed.
bytesRead += [self read:buffer+bytesRead maxLength:len-bytesRead];
else {
[self nextElement];
}
if (readElementCursor <= [self totalElements]) {
if (bytesRead < len) {
bytesRead += [self read:buffer+bytesRead maxLength:len-bytesRead];
} else {
// no deeper recursion so call callback if necessary
if (copiedCallback && (requestedEvents & kCFStreamEventHasBytesAvailable)) {
copiedCallback((CFReadStreamRef)self, kCFStreamEventHasBytesAvailable, &copiedContext);
}
}
}
//doesn't seem to make a diff if we do the callbacks or not for the HTTP request use anyway,
//and it sometimes crashes if the callback reciever or context have been released.
// if (CFReadStreamGetStatus((CFReadStreamRef)self) == kCFStreamStatusOpen) {
// double delayInSeconds = 0;
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
// dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// if (copiedCallback && (requestedEvents & kCFStreamEventHasBytesAvailable)) {
// NSLog(@"callback kCFStreamEventHasBytesAvailable... bytes read: %d", bytesRead);
// copiedCallback((CFReadStreamRef)self, kCFStreamEventHasBytesAvailable, &copiedContext);
// }
// });
// }
assert(bytesRead > 0); //really should never return zero from this call
return bytesRead;
}
-(BOOL)hasBytesAvailable {
if ([self totalElements] == 0) {
if ([self streamStatus] != NSStreamStatusOpen) {
return NO;
} else if (readElementCursor < ([self totalElements] + 1)) {
}
else {
return YES;
} else {
return NO;
}
}
@ -1161,7 +1158,6 @@ static inline NSString * AFMultipartFormFinalBoundary() {
}
@end