@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2021 Jonathan Schleifer + * Copyright (c) 2008-2022 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -46,10 +46,15 @@ #import "OFWriteFailedException.h" #ifdef OF_WINDOWS # include #endif + +#ifdef OF_AMIGAOS +# include +# include +#endif #ifdef OF_WII # include #endif @@ -56,13 +61,14 @@ #ifdef OF_NINTENDO_DS # include # include #endif -#ifdef OF_AMIGAOS -# include -# include +#ifdef OF_NINTENDO_SWITCH +# define id nx_id +# include +# undef id #endif #ifndef O_BINARY # define O_BINARY 0 #endif @@ -77,28 +83,32 @@ #endif #ifndef OF_AMIGAOS # define closeHandle(h) close(h) #else -static struct _OFFileHandle +static struct _OFFileHandle { struct _OFFileHandle *previous, *next; BPTR handle; bool append; } *firstHandle = NULL; static void closeHandle(OFFileHandle handle) { Close(handle->handle); + + Forbid(); if (handle->previous != NULL) handle->previous->next = handle->next; if (handle->next != NULL) handle->next->previous = handle->previous; if (firstHandle == handle) firstHandle = handle->next; + + Permit(); OFFreeMemory(handle); } OF_DESTRUCTOR() @@ -178,32 +188,31 @@ #ifdef OF_NINTENDO_DS if (!nitroFSInit(NULL)) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif + +#ifdef OF_NINTENDO_SWITCH + if (R_SUCCEEDED(romfsInit())) + /* + * Errors are intentionally ignored, as it's possible we just + * have no romfs. + */ + atexit((void (*)(void))romfsExit); +#endif } + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } -+ (instancetype)fileWithURL: (OFURL *)URL mode: (OFString *)mode -{ - return [[[self alloc] initWithURL: URL mode: mode] autorelease]; -} - + (instancetype)fileWithHandle: (OFFileHandle)handle { return [[[self alloc] initWithHandle: handle] autorelease]; } -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode { OFFileHandle handle; @try { @@ -289,18 +298,22 @@ exceptionWithPath: path mode: mode errNo: EIO]; } } + + Forbid(); handle->previous = NULL; handle->next = firstHandle; if (firstHandle != NULL) firstHandle->previous = handle; firstHandle = handle; + + Permit(); } @catch (id e) { OFFreeMemory(handle); @throw e; } #endif @@ -319,37 +332,23 @@ } return self; } -- (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode -{ - void *pool = objc_autoreleasePoolPush(); - OFString *fileSystemRepresentation; - - @try { - fileSystemRepresentation = URL.fileSystemRepresentation; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithPath: fileSystemRepresentation mode: mode]; - - objc_autoreleasePoolPop(pool); - - return self; -} - - (instancetype)initWithHandle: (OFFileHandle)handle { self = [super init]; _handle = handle; return self; } + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} - (bool)lowlevelIsAtEndOfStream { if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self];