96 lines
4.3 KiB
Objective-C
96 lines
4.3 KiB
Objective-C
#import <Foundation/Foundation.h>
|
|
#include <iron_net.h>
|
|
#import <objc/runtime.h>
|
|
|
|
volatile uint64_t iron_net_bytes_downloaded = 0;
|
|
static NSURLSession *download_session = nil;
|
|
|
|
@interface IronDownloadDelegate : NSObject <NSURLSessionDownloadDelegate>
|
|
@end
|
|
|
|
@implementation IronDownloadDelegate
|
|
|
|
- (void)URLSession:(NSURLSession *)session
|
|
downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
|
didWriteData:(int64_t)bytesWritten
|
|
totalBytesWritten:(int64_t)totalBytesWritten
|
|
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
|
|
iron_net_bytes_downloaded += bytesWritten;
|
|
}
|
|
|
|
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
|
|
NSString *dstPath = objc_getAssociatedObject(downloadTask, @"dst_path");
|
|
if (dstPath) {
|
|
NSError *error = nil;
|
|
NSURL *destURL = [NSURL fileURLWithPath:dstPath];
|
|
[[NSFileManager defaultManager] moveItemAtURL:location toURL:destURL error:&error];
|
|
// todo
|
|
if ([dstPath hasSuffix:@"sd_vulkan"] || [dstPath hasSuffix:@"sd_cpu"]) {
|
|
NSDictionary *attrs = @{NSFilePosixPermissions : @0755};
|
|
NSError *chmodError = nil;
|
|
[[NSFileManager defaultManager] setAttributes:attrs ofItemAtPath:dstPath error:&chmodError];
|
|
}
|
|
}
|
|
else {
|
|
NSData *fileData = [NSData dataWithContentsOfURL:location options:NSDataReadingMappedIfSafe error:nil];
|
|
NSMutableData *memoryData = objc_getAssociatedObject(downloadTask, @"memoryData");
|
|
[memoryData appendData:fileData];
|
|
}
|
|
}
|
|
|
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
|
NSURLSessionDownloadTask *downloadTask = (NSURLSessionDownloadTask *)task;
|
|
NSValue *cbVal = objc_getAssociatedObject(task, @"callback");
|
|
NSValue *dataVal = objc_getAssociatedObject(task, @"callbackdata");
|
|
NSString *dstPath = objc_getAssociatedObject(task, @"dst_path");
|
|
NSMutableData *memoryData = objc_getAssociatedObject(task, @"memoryData");
|
|
iron_https_callback_t callback = cbVal ? [cbVal pointerValue] : NULL;
|
|
void *callbackdata = dataVal ? [dataVal pointerValue] : NULL;
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
if (dstPath) {
|
|
callback(NULL, callbackdata);
|
|
}
|
|
else {
|
|
char *buffer = malloc(memoryData.length + 1);
|
|
memcpy(buffer, memoryData.bytes, memoryData.length);
|
|
buffer[memoryData.length] = '\0';
|
|
callback(buffer, callbackdata);
|
|
}
|
|
});
|
|
}
|
|
|
|
@end
|
|
|
|
void iron_net_request(const char *url_base, const char *url_path, const char *data, int port, int method, iron_https_callback_t callback, void *callbackdata,
|
|
const char *dst_path) {
|
|
if (!download_session) {
|
|
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
|
|
queue.qualityOfService = NSQualityOfServiceUtility;
|
|
|
|
static IronDownloadDelegate *delegate = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
delegate = [[IronDownloadDelegate alloc] init];
|
|
});
|
|
download_session = [NSURLSession sessionWithConfiguration:config delegate:delegate delegateQueue:queue];
|
|
}
|
|
|
|
NSString *urlStr =
|
|
[NSString stringWithFormat:@"https://%@:%d/%@", [NSString stringWithUTF8String:url_base], port, [NSString stringWithUTF8String:url_path]];
|
|
NSURL *url = [NSURL URLWithString:urlStr];
|
|
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
|
|
request.HTTPMethod = (method == IRON_HTTPS_GET) ? @"GET" : @"POST";
|
|
|
|
NSURLSessionDownloadTask *task = [download_session downloadTaskWithRequest:request];
|
|
objc_setAssociatedObject(task, @"callback", [NSValue valueWithPointer:callback], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
objc_setAssociatedObject(task, @"callbackdata", [NSValue valueWithPointer:callbackdata], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
objc_setAssociatedObject(task, @"dst_path", dst_path ? [NSString stringWithUTF8String:dst_path] : nil, OBJC_ASSOCIATION_COPY_NONATOMIC);
|
|
if (!dst_path) {
|
|
objc_setAssociatedObject(task, @"memoryData", [NSMutableData data], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
}
|
|
[task resume];
|
|
}
|
|
|
|
void iron_net_update() {}
|