ObjFW  Diff

Differences From Artifact [cb70217adb]:

  • File src/OFEmbeddedIRIHandler.m — part of check-in [9d802a786d] at 2025-01-01 12:58:18 on branch trunk — Update copyright (user: js size: 4315) [more...]

To Artifact [bd63da2d45]:

  • File src/OFEmbeddedIRIHandler.m — part of check-in [83237c1826] at 2025-03-15 09:10:18 on branch trunk — OFEmbeddedIRIHandler: Optimize lookup (user: js size: 5039) [more...]

20
21
22
23
24
25
26


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78






























79
80
81
82
83
84
85
#include "config.h"

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#import "OFEmbeddedIRIHandler.h"


#import "OFIRI.h"
#import "OFMemoryStream.h"
#import "OFNumber.h"

#import "OFGetItemAttributesFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOpenItemFailedException.h"

#ifdef OF_HAVE_THREADS
# import "OFOnce.h"
# import "OFPlainMutex.h"
#endif

static struct EmbeddedFile {
	OFString *path;
	const uint8_t *bytes;
	size_t size;
} *embeddedFiles = NULL;
static size_t numEmbeddedFiles = 0;

#ifdef OF_HAVE_THREADS
static OFPlainMutex mutex;
static OFOnceControl mutexOnceControl = OFOnceControlInitValue;

static void
initMutex(void)
{
	OFEnsure(OFPlainMutexNew(&mutex) == 0);
}
#endif

void
OFRegisterEmbeddedFile(OFString *path, const uint8_t *bytes, size_t size)
{
#ifdef OF_HAVE_THREADS
	OFOnce(&mutexOnceControl, initMutex);

	OFEnsure(OFPlainMutexLock(&mutex) == 0);
#endif

	embeddedFiles = realloc(embeddedFiles,
	    sizeof(*embeddedFiles) * (numEmbeddedFiles + 1));
	OFEnsure(embeddedFiles != NULL);

	embeddedFiles[numEmbeddedFiles].path = path;
	embeddedFiles[numEmbeddedFiles].bytes = bytes;
	embeddedFiles[numEmbeddedFiles].size = size;
	numEmbeddedFiles++;

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
#endif
}































@implementation OFEmbeddedIRIHandler
#ifdef OF_HAVE_THREADS
+ (void)initialize
{
	if (self == [OFEmbeddedIRIHandler class])
		OFOnce(&mutexOnceControl, initMutex);







>
>

















|
|
>




















|
|
|

|
|
|
|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "config.h"

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#import "OFEmbeddedIRIHandler.h"
#import "OFData.h"
#import "OFDictionary.h"
#import "OFIRI.h"
#import "OFMemoryStream.h"
#import "OFNumber.h"

#import "OFGetItemAttributesFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFOpenItemFailedException.h"

#ifdef OF_HAVE_THREADS
# import "OFOnce.h"
# import "OFPlainMutex.h"
#endif

static struct EmbeddedFile {
	OFString *path;
	const uint8_t *bytes;
	size_t size;
} *embeddedFilesQueue = NULL;
static size_t embeddedFilesQueueCount = 0;
static OFMutableDictionary *embeddedFiles = nil;
#ifdef OF_HAVE_THREADS
static OFPlainMutex mutex;
static OFOnceControl mutexOnceControl = OFOnceControlInitValue;

static void
initMutex(void)
{
	OFEnsure(OFPlainMutexNew(&mutex) == 0);
}
#endif

void
OFRegisterEmbeddedFile(OFString *path, const uint8_t *bytes, size_t size)
{
#ifdef OF_HAVE_THREADS
	OFOnce(&mutexOnceControl, initMutex);

	OFEnsure(OFPlainMutexLock(&mutex) == 0);
#endif

	embeddedFilesQueue = realloc(embeddedFilesQueue,
	    sizeof(*embeddedFilesQueue) * (embeddedFilesQueueCount + 1));
	OFEnsure(embeddedFilesQueue != NULL);

	embeddedFilesQueue[embeddedFilesQueueCount].path = path;
	embeddedFilesQueue[embeddedFilesQueueCount].bytes = bytes;
	embeddedFilesQueue[embeddedFilesQueueCount].size = size;
	embeddedFilesQueueCount++;

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
#endif
}

static void
processQueueLocked(void)
{
	void *pool;

	if (embeddedFilesQueueCount == 0)
		return;

	if (embeddedFiles == nil)
		embeddedFiles = [[OFMutableDictionary alloc] init];

	pool = objc_autoreleasePoolPush();

	for (size_t i = 0; i < embeddedFilesQueueCount; i++) {
		OFData *data = [OFData
		    dataWithItemsNoCopy: (void *)embeddedFilesQueue[i].bytes
				  count: embeddedFilesQueue[i].size
			   freeWhenDone: false];

		[embeddedFiles setObject: data
				  forKey: embeddedFilesQueue[i].path];
	}

	free(embeddedFilesQueue);
	embeddedFilesQueue = NULL;
	embeddedFilesQueueCount = 0;

	objc_autoreleasePoolPop(pool);
}

@implementation OFEmbeddedIRIHandler
#ifdef OF_HAVE_THREADS
+ (void)initialize
{
	if (self == [OFEmbeddedIRIHandler class])
		OFOnce(&mutexOnceControl, initMutex);
104
105
106
107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125
126
127
		@throw [OFInvalidArgumentException exception];
	}

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexLock(&mutex) == 0);
	@try {
#endif
		for (size_t i = 0; i < numEmbeddedFiles; i++) {
			if (![embeddedFiles[i].path isEqual: path])
				continue;


			return [OFMemoryStream
			    streamWithMemoryAddress: (void *)
							 embeddedFiles[i].bytes
					       size: embeddedFiles[i].size
					   writable: false];
		}
#ifdef OF_HAVE_THREADS
	} @finally {
		OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
	}
#endif

	@throw [OFOpenItemFailedException exceptionWithIRI: IRI







|
|
|

>

|
<
|

<







137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152

153
154
155
156
157
158
159
		@throw [OFInvalidArgumentException exception];
	}

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexLock(&mutex) == 0);
	@try {
#endif
		OFData *data;

		processQueueLocked();

		if ((data = [embeddedFiles objectForKey: path]) != nil)
			return [OFMemoryStream
			    streamWithMemoryAddress: (void *)data.items

					       size: data.count
					   writable: false];

#ifdef OF_HAVE_THREADS
	} @finally {
		OFEnsure(OFPlainMutexUnlock(&mutex) == 0);
	}
#endif

	@throw [OFOpenItemFailedException exceptionWithIRI: IRI
142
143
144
145
146
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162
163
		@throw [OFInvalidArgumentException exception];
	}

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexLock(&mutex) == 0);
	@try {
#endif
		for (size_t i = 0; i < numEmbeddedFiles; i++) {
			OFNumber *fileSize;

			if (![embeddedFiles[i].path isEqual: path])
				continue;



			fileSize = [OFNumber numberWithUnsignedLongLong:
			    embeddedFiles[i].size];

			return [OFDictionary dictionaryWithKeysAndObjects:
			    OFFileSize, fileSize,
			    OFFileType, OFFileTypeRegular,
			    nil];
		}
#ifdef OF_HAVE_THREADS







<
|

<
|

>
>
|
<







174
175
176
177
178
179
180

181
182

183
184
185
186
187

188
189
190
191
192
193
194
		@throw [OFInvalidArgumentException exception];
	}

#ifdef OF_HAVE_THREADS
	OFEnsure(OFPlainMutexLock(&mutex) == 0);
	@try {
#endif

		OFData *data;


		processQueueLocked();

		if ((data = [embeddedFiles objectForKey: path]) != nil) {
			OFNumber *fileSize = [OFNumber
			    numberWithUnsignedLongLong: data.count];


			return [OFDictionary dictionaryWithKeysAndObjects:
			    OFFileSize, fileSize,
			    OFFileType, OFFileTypeRegular,
			    nil];
		}
#ifdef OF_HAVE_THREADS