Fix downloads being cut off early
This commit is contained in:
parent
d035db7f0c
commit
315af41624
|
@ -14,6 +14,8 @@ struct download_context;
|
||||||
BOOL completed;
|
BOOL completed;
|
||||||
BOOL cancelled;
|
BOOL cancelled;
|
||||||
NSUInteger size;
|
NSUInteger size;
|
||||||
|
NSUInteger confirmedSize, sizeUntilNow;
|
||||||
|
NSLock *confirmedSizeLock;
|
||||||
NSUInteger written;
|
NSUInteger written;
|
||||||
NSInteger index;
|
NSInteger index;
|
||||||
NSDate *startDate;
|
NSDate *startDate;
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
#import "desktop/download.h"
|
#import "desktop/download.h"
|
||||||
#import "Preferences.h"
|
#import "Preferences.h"
|
||||||
|
|
||||||
|
@interface DownloadItem(Private)
|
||||||
|
-(void) completeAndNotifyManager;
|
||||||
|
-(void) notifyManager;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation DownloadItem
|
@implementation DownloadItem
|
||||||
|
|
||||||
-(id)initWithManager: (DownloadManager*)aManager destination: (NSURL*)aDestination size: (NSInteger)aSize index: (NSUInteger)anIndex ctx: (struct download_context*)aCtx {
|
-(id)initWithManager: (DownloadManager*)aManager destination: (NSURL*)aDestination size: (NSInteger)aSize index: (NSUInteger)anIndex ctx: (struct download_context*)aCtx {
|
||||||
|
@ -10,6 +15,8 @@
|
||||||
error = nil;
|
error = nil;
|
||||||
index = anIndex;
|
index = anIndex;
|
||||||
written = 0;
|
written = 0;
|
||||||
|
confirmedSize = 0;
|
||||||
|
confirmedSizeLock = [[NSLock alloc] init];
|
||||||
completed = NO;
|
completed = NO;
|
||||||
size = aSize;
|
size = aSize;
|
||||||
startDate = [[NSDate date] retain];
|
startDate = [[NSDate date] retain];
|
||||||
|
@ -29,12 +36,15 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: - Why isn't this releasing?
|
||||||
-(void)dealloc {
|
-(void)dealloc {
|
||||||
|
NSLog(@"DownloadItem dealloc!!");
|
||||||
runThread = NO;
|
runThread = NO;
|
||||||
[destination release];
|
[destination release];
|
||||||
[outputStream close];
|
[outputStream close];
|
||||||
[outputStream release];
|
[outputStream release];
|
||||||
[startDate release];
|
[startDate release];
|
||||||
|
[confirmedSizeLock release];
|
||||||
if (error) {
|
if (error) {
|
||||||
[error release];
|
[error release];
|
||||||
}
|
}
|
||||||
|
@ -56,11 +66,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)appendToDownload: (NSData*)data {
|
-(BOOL)appendToDownload: (NSData*)data {
|
||||||
|
sizeUntilNow += [data length];
|
||||||
if (downloadThread == nil) {
|
if (downloadThread == nil) {
|
||||||
NSLog(@"Error: expected download thread to be initialized");
|
NSLog(@"Error: expected download thread to be initialized");
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
[data retain];
|
|
||||||
[self performSelector: @selector(reallyWriteData:) onThread: downloadThread
|
[self performSelector: @selector(reallyWriteData:) onThread: downloadThread
|
||||||
withObject: data waitUntilDone: NO modes: [NSArray arrayWithObject:
|
withObject: data waitUntilDone: NO modes: [NSArray arrayWithObject:
|
||||||
NSDefaultRunLoopMode]];
|
NSDefaultRunLoopMode]];
|
||||||
|
@ -68,9 +78,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)reallyWriteData: (NSData*)data {
|
-(void)reallyWriteData: (NSData*)data {
|
||||||
NSUInteger len = [data length];
|
NSUInteger toWrite = [data length];
|
||||||
NSUInteger writtenNow = [outputStream write: [data bytes] maxLength: len];
|
NSInteger thisWrite;
|
||||||
written += writtenNow;
|
const uint8_t *start = [data bytes];
|
||||||
|
while (toWrite > 0) {
|
||||||
|
thisWrite = [outputStream write: start maxLength: toWrite];
|
||||||
|
start += thisWrite;
|
||||||
|
toWrite -= thisWrite;
|
||||||
|
}
|
||||||
|
written += [data length];
|
||||||
// Unless im misunderstanding download_context_get_total_length appears to return
|
// Unless im misunderstanding download_context_get_total_length appears to return
|
||||||
// a too-small non-zero value for download size when called so...
|
// a too-small non-zero value for download size when called so...
|
||||||
size = MAX(written, size);
|
size = MAX(written, size);
|
||||||
|
@ -81,6 +97,25 @@
|
||||||
waitUntilDone: NO];
|
waitUntilDone: NO];
|
||||||
}
|
}
|
||||||
lastWrite = time;
|
lastWrite = time;
|
||||||
|
|
||||||
|
// Check if we're complete.
|
||||||
|
BOOL done;
|
||||||
|
[confirmedSizeLock lock];
|
||||||
|
done = confirmedSize > 0 && written >= confirmedSize;
|
||||||
|
[confirmedSizeLock unlock];
|
||||||
|
if (done) {
|
||||||
|
[self performSelectorOnMainThread: @selector(completeAndNotifyManager)
|
||||||
|
withObject: nil waitUntilDone: NO];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-(void)completeAndNotifyManager {
|
||||||
|
completed = YES;
|
||||||
|
runThread = NO;
|
||||||
|
[outputStream close];
|
||||||
|
[[manager delegate] downloadManager: manager didUpdateItem: self];
|
||||||
|
if ([[Preferences defaultPreferences] removeDownloadsOnComplete]) {
|
||||||
|
[manager removeDownloadsAtIndexes: [NSIndexSet indexSetWithIndex: index]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
-(void)notifyManager {
|
-(void)notifyManager {
|
||||||
[[manager delegate] downloadManager: manager didUpdateItem: self];
|
[[manager delegate] downloadManager: manager didUpdateItem: self];
|
||||||
|
@ -104,12 +139,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)complete {
|
-(void)complete {
|
||||||
[outputStream close];
|
NSLog(@"Complete called...");
|
||||||
completed = YES;
|
// Having set this non-0, our download thread will know to complete.
|
||||||
[[manager delegate] downloadManager: manager didUpdateItem: self];
|
[confirmedSizeLock lock];
|
||||||
if ([[Preferences defaultPreferences] removeDownloadsOnComplete]) {
|
confirmedSize = sizeUntilNow;
|
||||||
[manager removeDownloadsAtIndexes: [NSIndexSet indexSetWithIndex: index]];
|
[confirmedSizeLock unlock];
|
||||||
}
|
// Trigger a write just to trigger the completion check if there's no data
|
||||||
|
// pending write.
|
||||||
|
[self appendToDownload: [NSData data]];
|
||||||
}
|
}
|
||||||
|
|
||||||
-(BOOL)isComplete {
|
-(BOOL)isComplete {
|
||||||
|
|
|
@ -110,7 +110,6 @@ static struct gui_download_window *gnustep_download_create(struct download_conte
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
static nserror gnustep_download_data(struct gui_download_window *dw, const char *data, unsigned int size) {
|
static nserror gnustep_download_data(struct gui_download_window *dw, const char *data, unsigned int size) {
|
||||||
NSLog(@"gnustep_download_data");
|
|
||||||
BOOL success = [(id)dw appendToDownload: [NSData dataWithBytesNoCopy: (void*)data
|
BOOL success = [(id)dw appendToDownload: [NSData dataWithBytesNoCopy: (void*)data
|
||||||
length: size freeWhenDone: NO]];
|
length: size freeWhenDone: NO]];
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
Loading…
Reference in New Issue