@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 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 @@ -17,13 +17,13 @@ #include #include #include -#import "OFEmbeddedURIHandler.h" +#import "OFEmbeddedIRIHandler.h" +#import "OFIRI.h" #import "OFMemoryStream.h" -#import "OFURI.h" #import "OFInvalidArgumentException.h" #import "OFOpenItemFailedException.h" #ifdef OF_HAVE_THREADS @@ -30,74 +30,82 @@ # import "OFOnce.h" # import "OFPlainMutex.h" #endif struct EmbeddedFile { - const char *name; + OFString *path; const uint8_t *bytes; size_t size; } *embeddedFiles = NULL; size_t numEmbeddedFiles = 0; #ifdef OF_HAVE_THREADS static OFPlainMutex mutex; +static OFOnceControl mutexOnceControl = OFOnceControlInitValue; static void -init(void) +initMutex(void) { OFEnsure(OFPlainMutexNew(&mutex) == 0); } #endif void -OFRegisterEmbeddedFile(const char *name, const uint8_t *bytes, size_t size) +OFRegisterEmbeddedFile(OFString *path, const uint8_t *bytes, size_t size) { #ifdef OF_HAVE_THREADS - static OFOnceControl onceControl = OFOnceControlInitValue; - OFOnce(&onceControl, init); + OFOnce(&mutexOnceControl, initMutex); OFEnsure(OFPlainMutexLock(&mutex) == 0); #endif embeddedFiles = realloc(embeddedFiles, sizeof(*embeddedFiles) * (numEmbeddedFiles + 1)); OFEnsure(embeddedFiles != NULL); - embeddedFiles[numEmbeddedFiles].name = name; + embeddedFiles[numEmbeddedFiles].path = path; embeddedFiles[numEmbeddedFiles].bytes = bytes; embeddedFiles[numEmbeddedFiles].size = size; numEmbeddedFiles++; #ifdef OF_HAVE_THREADS OFEnsure(OFPlainMutexUnlock(&mutex) == 0); #endif } -@implementation OFEmbeddedURIHandler -- (OFStream *)openItemAtURI: (OFURI *)URI mode: (OFString *)mode -{ - const char *path; - - if (![URI.scheme isEqual: @"embedded"] || URI.host.length > 0 || - URI.port != nil || URI.user != nil || URI.password != nil || - URI.query != nil || URI.fragment != nil) +@implementation OFEmbeddedIRIHandler +#ifdef OF_HAVE_THREADS ++ (void)initialize +{ + if (self == [OFEmbeddedIRIHandler class]) + OFOnce(&mutexOnceControl, initMutex); +} +#endif + +- (OFStream *)openItemAtIRI: (OFIRI *)IRI mode: (OFString *)mode +{ + OFString *path; + + if (![IRI.scheme isEqual: @"embedded"] || IRI.host.length > 0 || + IRI.port != nil || IRI.user != nil || IRI.password != nil || + IRI.query != nil || IRI.fragment != nil) @throw [OFInvalidArgumentException exception]; if (![mode isEqual: @"r"]) - @throw [OFOpenItemFailedException exceptionWithURI: URI + @throw [OFOpenItemFailedException exceptionWithIRI: IRI mode: mode errNo: EROFS]; - if ((path = URI.path.UTF8String) == NULL) { + if ((path = IRI.path) == nil) { @throw [OFInvalidArgumentException exception]; } #ifdef OF_HAVE_THREADS OFEnsure(OFPlainMutexLock(&mutex) == 0); @try { #endif for (size_t i = 0; i < numEmbeddedFiles; i++) { - if (strcmp(embeddedFiles[i].name, path) != 0) + if (![embeddedFiles[i].path isEqual: path]) continue; return [OFMemoryStream streamWithMemoryAddress: (void *) embeddedFiles[i].bytes @@ -108,10 +116,10 @@ } @finally { OFEnsure(OFPlainMutexUnlock(&mutex) == 0); } #endif - @throw [OFOpenItemFailedException exceptionWithURI: URI + @throw [OFOpenItemFailedException exceptionWithIRI: IRI mode: mode errNo: ENOENT]; } @end