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
|
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;
} *embeddedFiles = NULL;
static size_t numEmbeddedFiles = 0;
} *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
embeddedFiles = realloc(embeddedFiles,
sizeof(*embeddedFiles) * (numEmbeddedFiles + 1));
OFEnsure(embeddedFiles != NULL);
embeddedFilesQueue = realloc(embeddedFilesQueue,
sizeof(*embeddedFilesQueue) * (embeddedFilesQueueCount + 1));
OFEnsure(embeddedFilesQueue != NULL);
embeddedFiles[numEmbeddedFiles].path = path;
embeddedFiles[numEmbeddedFiles].bytes = bytes;
embeddedFiles[numEmbeddedFiles].size = size;
numEmbeddedFiles++;
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
|
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
for (size_t i = 0; i < numEmbeddedFiles; i++) {
if (![embeddedFiles[i].path isEqual: path])
continue;
OFData *data;
processQueueLocked();
if ((data = [embeddedFiles objectForKey: path]) != nil)
return [OFMemoryStream
streamWithMemoryAddress: (void *)
streamWithMemoryAddress: (void *)data.items
embeddedFiles[i].bytes
size: embeddedFiles[i].size
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
|
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
for (size_t i = 0; i < numEmbeddedFiles; i++) {
OFNumber *fileSize;
OFData *data;
if (![embeddedFiles[i].path isEqual: path])
continue;
processQueueLocked();
if ((data = [embeddedFiles objectForKey: path]) != nil) {
OFNumber *fileSize = [OFNumber
fileSize = [OFNumber numberWithUnsignedLongLong:
numberWithUnsignedLongLong: data.count];
embeddedFiles[i].size];
return [OFDictionary dictionaryWithKeysAndObjects:
OFFileSize, fileSize,
OFFileType, OFFileTypeRegular,
nil];
}
#ifdef OF_HAVE_THREADS
|