From 36a26db7848f4b59fb3ce716b748339ba83c05d2 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Sat, 23 Dec 2017 16:01:56 +0100 Subject: Fix code to determine MIME type and implement data loading. --- frontends/cocoa/fetch.m | 133 +++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 57 deletions(-) diff --git a/frontends/cocoa/fetch.m b/frontends/cocoa/fetch.m index 1e3e5af13..764f25438 100644 --- a/frontends/cocoa/fetch.m +++ b/frontends/cocoa/fetch.m @@ -26,87 +26,106 @@ static char cocoafiletype[200]; -static const struct mimemap_s { - const char *const extension; - const char *const mimetype; -} cocoamimemap[] = { - { "css", "text/css" }, - { "f79", "text/css" }, - { "jpg", "image/jpeg" }, - { "jpeg", "image/jpeg" }, - { "gif", "image/gif" }, - { "png", "image/png" }, - { "b60", "image/png" }, - { "jng", "image/jng" }, - { "svg", "image/svg" }, - { NULL, "text/html" } -}; - static const char *fetch_filetype(const char *unix_path) { - NSString *uti; - NSString *mimeType = nil; - NSError *utiError = nil; - - uti = [[NSWorkspace sharedWorkspace] typeOfFile:[NSString stringWithUTF8String:unix_path] error:&utiError]; - if (nil != uti) { - NSLOG(netsurf, INFO, "Looking for mimetype from uti \"%s\"", [uti UTF8String]); - mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassMIMEType); - } else { - NSAlert *utiAlert = [NSAlert alertWithError:utiError]; - [utiAlert runModal]; // Ignore return value. - - NSLOG(netsurf, INFO, "uti call failed"); - - strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); - return cocoafiletype; + NSString *path = @(unix_path); + NSString *uti = [[NSWorkspace sharedWorkspace] typeOfFile:path error:NULL]; + if (uti == nil) { + // If the file was not found look up the UTI from the file extension. + uti = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)path.pathExtension, nil); } - if (nil != mimeType) { - strncpy(cocoafiletype, [mimeType UTF8String], sizeof(cocoafiletype)); - } else { - const char *extension; + if (uti == nil) { + // We can’t determine the UTI, let’s pretend this is HTML. + return "text/html"; + } - NSLOG(netsurf, INFO, "mimetype from uti failed"); + NSString *mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassMIMEType); - extension = [(__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti, kUTTagClassFilenameExtension) UTF8String]; + strncpy(cocoafiletype, [mimeType cStringUsingEncoding: NSUTF8StringEncoding], sizeof cocoafiletype); - if (extension == NULL) { - /* give up and go with default */ - NSLOG(netsurf, INFO, "No extension going with default type"); - strncpy(cocoafiletype, "text/html", sizeof(cocoafiletype)); - } else { - int eidx = 0; /* index of extension entry */ + NSLOG(netsurf, INFO, "\tMIME type for '%s' is '%s'", unix_path, cocoafiletype); - while ((cocoamimemap[eidx].extension != NULL) && (strcmp(cocoamimemap[eidx].extension, extension) != 0)) { - eidx++; - } + return cocoafiletype; +} - strncpy(cocoafiletype, - cocoamimemap[eidx].mimetype, - sizeof(cocoafiletype)); - } - } +static NSString *findResource(const char *path) { + NSString *pathString = @(path); + NSString *nspath = [[NSBundle mainBundle] pathForResource:pathString ofType:@""]; - NSLOG(netsurf, INFO, "\tMIME type for '%s' is '%s'", unix_path, cocoafiletype); + if (nspath == nil) { + nspath = [[NSBundle mainBundle] pathForResource: pathString ofType:@"" inDirectory:nil forLocalization:@"en"]; + } - return cocoafiletype; + return nspath; } static nsurl *gui_get_resource_url(const char *path) { - nsurl *url = NULL; - NSString *nspath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:path] ofType:@""]; - if (nspath == nil) + NSString *nspath = findResource(path); + if (nspath == nil) { return NULL; + } + + nsurl *url = NULL; nsurl_create([[[NSURL fileURLWithPath:nspath] absoluteString] UTF8String], &url); return url; } +static nserror cocoa_get_resource_data(const char *path, const uint8_t **data, size_t *data_len) +{ + NSString *resourcePath = findResource(path); + if (resourcePath == nil) { + return NSERROR_NOT_FOUND; + } + + int file = open(resourcePath.fileSystemRepresentation, O_RDONLY); + if (file < 0) { + return NSERROR_NOT_FOUND; + } + + int size = lseek(file, 0, SEEK_END); + if (size < 0) { + close(file); + return NSERROR_INVALID; + } + + void *buffer = malloc(size); + if (buffer == NULL) { + close(file); + return NSERROR_NOMEM; + } + + lseek(file, 0, SEEK_SET); + int readAmount = read(file, buffer, size); + + if (size != readAmount) { + free(buffer); + close(file); + return NSERROR_INVALID; + } + + *data = buffer; + *data_len = size; + + close(file); + + return NSERROR_OK; +} + +static nserror cocoa_release_resource_data(const uint8_t *data) +{ + free((void *)data); + return NSERROR_OK; +} + static struct gui_fetch_table fetch_table = { .filetype = fetch_filetype, .get_resource_url = gui_get_resource_url, + + .get_resource_data = cocoa_get_resource_data, + .release_resource_data = cocoa_release_resource_data, }; struct gui_fetch_table *cocoa_fetch_table = &fetch_table; -- cgit v1.2.3