Modified src/OFApplication.h
from [8e58702259]
to [4a2c8eebf0].
︙ | | | ︙ | |
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
@end
/*!
* @brief Represents the application as an object.
*/
@interface OFApplication: OFObject
{
OFString *programName;
OFMutableArray *arguments;
OFMutableDictionary *environment;
int *argc;
char ***argv;
@public
id <OFApplicationDelegate> delegate;
void (*SIGINTHandler)(id, SEL);
#ifndef _WIN32
void (*SIGHUPHandler)(id, SEL);
void (*SIGUSR1Handler)(id, SEL);
void (*SIGUSR2Handler)(id, SEL);
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *programName;
@property (readonly, copy, nonatomic) OFArray *arguments;
@property (readonly, copy, nonatomic) OFDictionary *environment;
|
|
|
|
|
|
|
|
|
|
|
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
@end
/*!
* @brief Represents the application as an object.
*/
@interface OFApplication: OFObject
{
OFString *_programName;
OFArray *_arguments;
OFDictionary *_environment;
int *_argc;
char ***_argv;
@public
id <OFApplicationDelegate> _delegate;
void (*_SIGINTHandler)(id, SEL);
#ifndef _WIN32
void (*_SIGHUPHandler)(id, SEL);
void (*_SIGUSR1Handler)(id, SEL);
void (*_SIGUSR2Handler)(id, SEL);
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *programName;
@property (readonly, copy, nonatomic) OFArray *arguments;
@property (readonly, copy, nonatomic) OFDictionary *environment;
|
︙ | | | ︙ | |
Modified src/OFApplication.m
from [af4f6fe02e]
to [10883a3ba0].
︙ | | | ︙ | |
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
atexit_handler(void)
{
id <OFApplicationDelegate> delegate = [app delegate];
if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
[delegate applicationWillTerminate];
[(id)delegate release];
}
#define SIGNAL_HANDLER(sig) \
static void \
handle##sig(int signal) \
{ \
app->sig##Handler(app->delegate, \
@selector(applicationDidReceive##sig)); \
}
SIGNAL_HANDLER(SIGINT)
#ifndef _WIN32
SIGNAL_HANDLER(SIGHUP)
SIGNAL_HANDLER(SIGUSR1)
SIGNAL_HANDLER(SIGUSR2)
|
|
|
|
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
atexit_handler(void)
{
id <OFApplicationDelegate> delegate = [app delegate];
if ([delegate respondsToSelector: @selector(applicationWillTerminate)])
[delegate applicationWillTerminate];
[delegate release];
}
#define SIGNAL_HANDLER(sig) \
static void \
handle##sig(int signal) \
{ \
app->_##sig##Handler(app->_delegate, \
@selector(applicationDidReceive##sig)); \
}
SIGNAL_HANDLER(SIGINT)
#ifndef _WIN32
SIGNAL_HANDLER(SIGHUP)
SIGNAL_HANDLER(SIGUSR1)
SIGNAL_HANDLER(SIGUSR2)
|
︙ | | | ︙ | |
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
- init
{
self = [super init];
@try {
void *pool;
#if defined(__MACH__) && !defined(OF_IOS)
char **env = *_NSGetEnviron();
#elif defined(__WIN32)
uint16_t *env;
#elif !defined(OF_IOS)
char **env = environ;
#else
|
>
|
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
- init
{
self = [super init];
@try {
void *pool;
OFMutableDictionary *environment;
#if defined(__MACH__) && !defined(OF_IOS)
char **env = *_NSGetEnviron();
#elif defined(__WIN32)
uint16_t *env;
#elif !defined(OF_IOS)
char **env = environ;
#else
|
︙ | | | ︙ | |
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
forKey: @"USER"];
}
objc_autoreleasePoolPop(pool);
#endif
[environment makeImmutable];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)OF_setArgumentCount: (int*)argc_
andArgumentValues: (char***)argv_
{
#ifndef _WIN32
void *pool = objc_autoreleasePoolPush();
int i;
argc = argc_;
argv = argv_;
programName = [[OFString alloc]
initWithCString: (*argv)[0]
encoding: OF_STRING_ENCODING_NATIVE];
arguments = [[OFMutableArray alloc] init];
for (i = 1; i < *argc; i++)
[arguments addObject:
[OFString stringWithCString: (*argv)[i]
encoding: OF_STRING_ENCODING_NATIVE]];
[arguments makeImmutable];
objc_autoreleasePoolPop(pool);
#else
argc = argc_;
argv = argv_;
#endif
}
#ifdef _WIN32
- (void)OF_setArgumentCount: (int)argc_
andWideArgumentValues: (wchar_t**)argv_
{
void *pool = objc_autoreleasePoolPush();
int i;
programName = [[OFString alloc] initWithUTF16String: argv_[0]];
arguments = [[OFMutableArray alloc] init];
for (i = 1; i < argc_; i++)
[arguments addObject:
[OFString stringWithUTF16String: argv_[i]]];
[arguments makeImmutable];
objc_autoreleasePoolPop(pool);
}
#endif
- (void)getArgumentCount: (int**)argc_
andArgumentValues: (char****)argv_
{
*argc_ = argc;
*argv_ = argv;
}
- (OFString*)programName
{
OF_GETTER(programName, NO)
}
- (OFArray*)arguments
{
OF_GETTER(arguments, NO)
}
- (OFDictionary*)environment
{
OF_GETTER(environment, NO)
}
- (id <OFApplicationDelegate>)delegate
{
return delegate;
}
- (void)setDelegate: (id <OFApplicationDelegate>)delegate_
{
delegate = delegate_;
#define REGISTER_SIGNAL(sig) \
if ([delegate respondsToSelector: \
@selector(applicationDidReceive##sig)]) { \
sig##Handler = (void(*)(id, SEL))[(id)delegate \
methodForSelector: \
@selector(applicationDidReceive##sig)]; \
signal(sig, handle##sig); \
} else \
signal(sig, SIG_DFL);
REGISTER_SIGNAL(SIGINT)
#ifndef _WIN32
|
>
>
>
>
>
>
>
>
>
|
|
>
|
|
|
>
|
|
|
|
>
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
forKey: @"USER"];
}
objc_autoreleasePoolPop(pool);
#endif
[environment makeImmutable];
_environment = environment;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_arguments release];
[_environment release];
[super dealloc];
}
- (void)OF_setArgumentCount: (int*)argc
andArgumentValues: (char***)argv
{
#ifndef _WIN32
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
int i;
_argc = argc;
_argv = argv;
_programName = [[OFString alloc]
initWithCString: (*argv)[0]
encoding: OF_STRING_ENCODING_NATIVE];
arguments = [[OFMutableArray alloc] init];
for (i = 1; i < *argc; i++)
[arguments addObject:
[OFString stringWithCString: (*argv)[i]
encoding: OF_STRING_ENCODING_NATIVE]];
[arguments makeImmutable];
_arguments = arguments;
objc_autoreleasePoolPop(pool);
#else
_argc = argc;
_argv = argv;
#endif
}
#ifdef _WIN32
- (void)OF_setArgumentCount: (int)argc
andWideArgumentValues: (wchar_t**)argv
{
void *pool = objc_autoreleasePoolPush();
OFMutableArray *arguments;
int i;
_programName = [[OFString alloc] initWithUTF16String: argv[0]];
arguments = [[OFMutableArray alloc] init];
for (i = 1; i < argc; i++)
[arguments addObject:
[OFString stringWithUTF16String: argv[i]]];
[arguments makeImmutable];
_arguments = arguments;
objc_autoreleasePoolPop(pool);
}
#endif
- (void)getArgumentCount: (int**)argc
andArgumentValues: (char****)argv
{
*argc = _argc;
*argv = _argv;
}
- (OFString*)programName
{
OF_GETTER(_programName, NO)
}
- (OFArray*)arguments
{
OF_GETTER(_arguments, NO)
}
- (OFDictionary*)environment
{
OF_GETTER(_environment, NO)
}
- (id <OFApplicationDelegate>)delegate
{
return _delegate;
}
- (void)setDelegate: (id <OFApplicationDelegate>)delegate
{
_delegate = delegate;
#define REGISTER_SIGNAL(sig) \
if ([delegate respondsToSelector: \
@selector(applicationDidReceive##sig)]) { \
_##sig##Handler = (void(*)(id, SEL))[(id)delegate \
methodForSelector: \
@selector(applicationDidReceive##sig)]; \
signal(sig, handle##sig); \
} else \
signal(sig, SIG_DFL);
REGISTER_SIGNAL(SIGINT)
#ifndef _WIN32
|
︙ | | | ︙ | |
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
|
runLoop = [[[OFRunLoop alloc] init] autorelease];
#endif
[OFRunLoop OF_setMainRunLoop: runLoop];
objc_autoreleasePoolPop(pool);
pool = objc_autoreleasePoolPush();
[delegate applicationDidFinishLaunching];
objc_autoreleasePoolPop(pool);
[runLoop run];
}
- (void)terminate
{
exit(0);
}
- (void)terminateWithStatus: (int)status
{
exit(status);
}
- (void)dealloc
{
[arguments release];
[environment release];
[super dealloc];
}
@end
|
>
>
>
>
>
>
|
<
<
<
<
<
<
<
<
|
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
runLoop = [[[OFRunLoop alloc] init] autorelease];
#endif
[OFRunLoop OF_setMainRunLoop: runLoop];
objc_autoreleasePoolPop(pool);
/*
* Note: runLoop is still valid after the release of the pool, as
* OF_setMainRunLoop: retained it. However, we only have a weak
* reference to it now, whereas we had a strong reference before.
*/
pool = objc_autoreleasePoolPush();
[_delegate applicationDidFinishLaunching];
objc_autoreleasePoolPop(pool);
[runLoop run];
}
- (void)terminate
{
exit(0);
}
- (void)terminateWithStatus: (int)status
{
exit(status);
}
@end
|
Modified src/OFArray_adjacent.h
from [df8cae2d28]
to [a695cf002b].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
|
#import "OFArray.h"
@class OFDataArray;
@interface OFArray_adjacent: OFArray
{
OFDataArray *array;
}
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
|
#import "OFArray.h"
@class OFDataArray;
@interface OFArray_adjacent: OFArray
{
OFDataArray *_array;
}
@end
|
Modified src/OFArray_adjacent.m
from [c91deb9080]
to [a68b59eaa5].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
|
@implementation OFArray_adjacent
- init
{
self = [super init];
@try {
array = [[OFDataArray alloc] initWithItemSize: sizeof(id)];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)object
{
self = [self init];
@try {
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[array addItem: &object];
[object retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)firstObject
arguments: (va_list)arguments
{
self = [self init];
@try {
id object;
[array addItem: &firstObject];
[firstObject retain];
while ((object = va_arg(arguments, id)) != nil) {
[array addItem: &object];
[object retain];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithArray: (OFArray*)array_
{
id *objects;
size_t i, count;
self = [self init];
if (array_ == nil)
return self;
@try {
objects = [array_ objects];
count = [array_ count];
} @catch (id e) {
[self release];
@throw e;
}
@try {
for (i = 0; i < count; i++)
[objects[i] retain];
[array addItems: objects
count: count];
} @catch (id e) {
for (i = 0; i < count; i++)
[objects[i] release];
/* Prevent double-release of objects */
[array release];
array = nil;
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
|
@implementation OFArray_adjacent
- init
{
self = [super init];
@try {
_array = [[OFDataArray alloc] initWithItemSize: sizeof(id)];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)object
{
self = [self init];
@try {
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[_array addItem: &object];
[object retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)firstObject
arguments: (va_list)arguments
{
self = [self init];
@try {
id object;
[_array addItem: &firstObject];
[firstObject retain];
while ((object = va_arg(arguments, id)) != nil) {
[_array addItem: &object];
[object retain];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithArray: (OFArray*)array
{
id *objects;
size_t i, count;
self = [self init];
if (array == nil)
return self;
@try {
objects = [array objects];
count = [array count];
} @catch (id e) {
[self release];
@throw e;
}
@try {
for (i = 0; i < count; i++)
[objects[i] retain];
[_array addItems: objects
count: count];
} @catch (id e) {
for (i = 0; i < count; i++)
[objects[i] release];
/* Prevent double-release of objects */
[_array release];
_array = nil;
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
[objects[i] retain];
}
if (!ok)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[array addItems: objects
count: count];
} @catch (id e) {
size_t i;
for (i = 0; i < count; i++)
[objects[i] release];
[self release];
|
|
|
|
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
[objects[i] retain];
}
if (!ok)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[_array addItems: objects
count: count];
} @catch (id e) {
size_t i;
for (i = 0; i < count; i++)
[objects[i] release];
[self release];
|
︙ | | | ︙ | |
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
OF_SERIALIZATION_NS] objectEnumerator];
while ((child = [enumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
id object;
object = [child objectByDeserializing];
[array addItem: &object];
[object retain];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (size_t)count
{
return [array count];
}
- (id*)objects
{
return [array items];
}
- (id)objectAtIndex: (size_t)index
{
return *((id*)[array itemAtIndex: index]);
}
- (id)objectAtIndexedSubscript: (size_t)index
{
return *((id*)[array itemAtIndex: index]);
}
- (void)getObjects: (id*)buffer
inRange: (of_range_t)range
{
id *objects = [array items];
size_t i, count = [array count];
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
for (i = 0; i < range.length; i++)
buffer[i] = objects[range.location + i];
}
- (size_t)indexOfObject: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
return OF_NOT_FOUND;
objects = [array items];
count = [array count];
for (i = 0; i < count; i++)
if ([objects[i] isEqual: object])
return i;
return OF_NOT_FOUND;
}
- (size_t)indexOfObjectIdenticalTo: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
return OF_NOT_FOUND;
objects = [array items];
count = [array count];
for (i = 0; i < count; i++)
if (objects[i] == object)
return i;
return OF_NOT_FOUND;
}
- (OFArray*)objectsInRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > [array count])
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
if ([self isKindOfClass: [OFMutableArray class]])
return [OFArray
arrayWithObjects: (id*)[array items] + range.location
count: range.length];
return [OFArray_adjacentSubarray arrayWithArray: self
range: range];
}
- (BOOL)isEqual: (id)object
{
OFArray *otherArray;
id *objects, *otherObjects;
size_t i, count;
if ([object class] != [OFArray_adjacent class] &&
[object class] != [OFMutableArray_adjacent class] &&
[object class] != [OFArray_adjacentSubarray class])
return [super isEqual: object];
otherArray = object;
count = [array count];
if (count != [otherArray count])
return NO;
objects = [array items];
otherObjects = [otherArray objects];
for (i = 0; i < count; i++)
if (![objects[i] isEqual: otherObjects[i]])
return NO;
return YES;
}
- (uint32_t)hash
{
id *objects = [array items];
size_t i, count = [array count];
uint32_t hash;
OF_HASH_INIT(hash);
for (i = 0; i < count; i++)
OF_HASH_ADD_HASH(hash, [objects[i] hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [array items];
size_t i, count = [array count];
BOOL stop = NO;
for (i = 0; i < count && !stop; i++)
block(objects[i], i, &stop);
}
#endif
- (void)dealloc
{
id *objects = [array items];
size_t i, count = [array count];
for (i = 0; i < count; i++)
[objects[i] release];
[array release];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
OF_SERIALIZATION_NS] objectEnumerator];
while ((child = [enumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
id object;
object = [child objectByDeserializing];
[_array addItem: &object];
[object retain];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (size_t)count
{
return [_array count];
}
- (id*)objects
{
return [_array items];
}
- (id)objectAtIndex: (size_t)index
{
return *((id*)[_array itemAtIndex: index]);
}
- (id)objectAtIndexedSubscript: (size_t)index
{
return *((id*)[_array itemAtIndex: index]);
}
- (void)getObjects: (id*)buffer
inRange: (of_range_t)range
{
id *objects = [_array items];
size_t i, count = [_array count];
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
for (i = 0; i < range.length; i++)
buffer[i] = objects[range.location + i];
}
- (size_t)indexOfObject: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
return OF_NOT_FOUND;
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++)
if ([objects[i] isEqual: object])
return i;
return OF_NOT_FOUND;
}
- (size_t)indexOfObjectIdenticalTo: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
return OF_NOT_FOUND;
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++)
if (objects[i] == object)
return i;
return OF_NOT_FOUND;
}
- (OFArray*)objectsInRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > [_array count])
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
if ([self isKindOfClass: [OFMutableArray class]])
return [OFArray
arrayWithObjects: (id*)[_array items] + range.location
count: range.length];
return [OFArray_adjacentSubarray arrayWithArray: self
range: range];
}
- (BOOL)isEqual: (id)object
{
OFArray *otherArray;
id *objects, *otherObjects;
size_t i, count;
if ([object class] != [OFArray_adjacent class] &&
[object class] != [OFMutableArray_adjacent class] &&
[object class] != [OFArray_adjacentSubarray class])
return [super isEqual: object];
otherArray = object;
count = [_array count];
if (count != [otherArray count])
return NO;
objects = [_array items];
otherObjects = [otherArray objects];
for (i = 0; i < count; i++)
if (![objects[i] isEqual: otherObjects[i]])
return NO;
return YES;
}
- (uint32_t)hash
{
id *objects = [_array items];
size_t i, count = [_array count];
uint32_t hash;
OF_HASH_INIT(hash);
for (i = 0; i < count; i++)
OF_HASH_ADD_HASH(hash, [objects[i] hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [_array items];
size_t i, count = [_array count];
BOOL stop = NO;
for (i = 0; i < count && !stop; i++)
block(objects[i], i, &stop);
}
#endif
- (void)dealloc
{
id *objects = [_array items];
size_t i, count = [_array count];
for (i = 0; i < count; i++)
[objects[i] release];
[_array release];
[super dealloc];
}
@end
|
Modified src/OFArray_adjacentSubarray.m
from [8222b3a3eb]
to [57128f3980].
︙ | | | ︙ | |
19
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
|
#import "OFArray_adjacentSubarray.h"
#import "OFArray_adjacent.h"
#import "OFMutableArray_adjacent.h"
@implementation OFArray_adjacentSubarray
- (id*)objects
{
return [array objects] + range.location;
}
- (BOOL)isEqual: (id)object
{
OFArray *otherArray;
id *objects, *otherObjects;
size_t i;
if ([object class] != [OFArray_adjacent class] &&
[object class] != [OFMutableArray_adjacent class] &&
[object class] != [OFArray_adjacentSubarray class])
return [super isEqual: object];
otherArray = object;
if (range.length != [otherArray count])
return NO;
objects = [self objects];
otherObjects = [otherArray objects];
for (i = 0; i < range.length; i++)
if (![objects[i] isEqual: otherObjects[i]])
return NO;
return YES;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [self objects];
size_t i;
BOOL stop = NO;
for (i = 0; i < range.length && !stop; i++)
block(objects[i], i, &stop);
}
#endif
@end
|
|
|
|
|
|
19
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
|
#import "OFArray_adjacentSubarray.h"
#import "OFArray_adjacent.h"
#import "OFMutableArray_adjacent.h"
@implementation OFArray_adjacentSubarray
- (id*)objects
{
return [_array objects] + _range.location;
}
- (BOOL)isEqual: (id)object
{
OFArray *otherArray;
id *objects, *otherObjects;
size_t i;
if ([object class] != [OFArray_adjacent class] &&
[object class] != [OFMutableArray_adjacent class] &&
[object class] != [OFArray_adjacentSubarray class])
return [super isEqual: object];
otherArray = object;
if (_range.length != [otherArray count])
return NO;
objects = [self objects];
otherObjects = [otherArray objects];
for (i = 0; i < _range.length; i++)
if (![objects[i] isEqual: otherObjects[i]])
return NO;
return YES;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [self objects];
size_t i;
BOOL stop = NO;
for (i = 0; i < _range.length && !stop; i++)
block(objects[i], i, &stop);
}
#endif
@end
|
Modified src/OFArray_subarray.h
from [2b2c04c402]
to [8e2aa92a1b].
︙ | | | ︙ | |
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
* file.
*/
#import "OFArray.h"
@interface OFArray_subarray: OFArray
{
OFArray *array;
of_range_t range;
}
+ (instancetype)arrayWithArray: (OFArray*)array
range: (of_range_t)range;
- initWithArray: (OFArray*)array
range: (of_range_t)range;
@end
|
|
|
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
* file.
*/
#import "OFArray.h"
@interface OFArray_subarray: OFArray
{
OFArray *_array;
of_range_t _range;
}
+ (instancetype)arrayWithArray: (OFArray*)array
range: (of_range_t)range;
- initWithArray: (OFArray*)array
range: (of_range_t)range;
@end
|
Modified src/OFArray_subarray.m
from [43b86d4da0]
to [4d0eadf9ff].
︙ | | | ︙ | |
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
119
120
121
|
+ (instancetype)arrayWithArray: (OFArray*)array
range: (of_range_t)range
{
return [[[self alloc] initWithArray: array
range: range] autorelease];
}
- initWithArray: (OFArray*)array_
range: (of_range_t)range_
{
self = [super init];
@try {
/* Should usually be retain, as it's useless with a copy */
array = [array_ copy];
range = range_;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[array release];
[super dealloc];
}
- (size_t)count
{
return range.length;
}
- (id)objectAtIndex: (size_t)index
{
if (index >= range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return [array objectAtIndex: index + range.location];
}
- (void)getObjects: (id*)buffer
inRange: (of_range_t)range_
{
if (range_.length > SIZE_MAX - range_.location ||
range_.location + range_.length > range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
range_.location += range.location;
return [array getObjects: buffer
inRange: range_];
}
- (size_t)indexOfObject: (id)object
{
size_t index = [array indexOfObject: object];
if (index < range.location)
return OF_NOT_FOUND;
index -= range.location;
if (index >= range.length)
return OF_NOT_FOUND;
return index;
}
- (size_t)indexOfObjectIdenticalTo: (id)object
{
size_t index = [array indexOfObjectIdenticalTo: object];
if (index < range.location)
return OF_NOT_FOUND;
index -= range.location;
if (index >= range.length)
return OF_NOT_FOUND;
return index;
}
- (OFArray*)objectsInRange: (of_range_t)range_
{
if (range_.length > SIZE_MAX - range_.location ||
range_.location + range_.length > range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
range_.location += range.location;
return [array objectsInRange: range_];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
|
+ (instancetype)arrayWithArray: (OFArray*)array
range: (of_range_t)range
{
return [[[self alloc] initWithArray: array
range: range] autorelease];
}
- initWithArray: (OFArray*)array
range: (of_range_t)range
{
self = [super init];
@try {
/* Should usually be retain, as it's useless with a copy */
_array = [array copy];
_range = range;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_array release];
[super dealloc];
}
- (size_t)count
{
return _range.length;
}
- (id)objectAtIndex: (size_t)index
{
if (index >= _range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return [_array objectAtIndex: index + _range.location];
}
- (void)getObjects: (id*)buffer
inRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
range.location += _range.location;
return [_array getObjects: buffer
inRange: range];
}
- (size_t)indexOfObject: (id)object
{
size_t index = [_array indexOfObject: object];
if (index < _range.location)
return OF_NOT_FOUND;
index -= _range.location;
if (index >= _range.length)
return OF_NOT_FOUND;
return index;
}
- (size_t)indexOfObjectIdenticalTo: (id)object
{
size_t index = [_array indexOfObjectIdenticalTo: object];
if (index < _range.location)
return OF_NOT_FOUND;
index -= _range.location;
if (index >= _range.length)
return OF_NOT_FOUND;
return index;
}
- (OFArray*)objectsInRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _range.length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
range.location += _range.location;
return [_array objectsInRange: range];
}
@end
|
Modified src/OFAutoreleasePool.h
from [6e97eee322]
to [c4bc0a71ca].
︙ | | | ︙ | |
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
* The OFAutoreleasePool class is a class that keeps track of objects that will
* be released when the autorelease pool is released.
*
* Every thread has its own stack of autorelease pools.
*/
@interface OFAutoreleasePool: OFObject
{
void *pool;
BOOL ignoreRelease;
}
/*!
* @brief Adds an object to the autorelease pool at the top of the
* thread-specific autorelease pool stack.
*
* @param object The object to add to the autorelease pool
|
|
|
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
* The OFAutoreleasePool class is a class that keeps track of objects that will
* be released when the autorelease pool is released.
*
* Every thread has its own stack of autorelease pools.
*/
@interface OFAutoreleasePool: OFObject
{
void *_pool;
BOOL _ignoreRelease;
}
/*!
* @brief Adds an object to the autorelease pool at the top of the
* thread-specific autorelease pool stack.
*
* @param object The object to add to the autorelease pool
|
︙ | | | ︙ | |
Modified src/OFAutoreleasePool.m
from [b51231d742]
to [d0fc457afc].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
}
- init
{
self = [super init];
@try {
pool = objc_autoreleasePoolPush();
_objc_rootAutorelease(self);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)releaseObjects
{
ignoreRelease = YES;
objc_autoreleasePoolPop(pool);
pool = objc_autoreleasePoolPush();
_objc_rootAutorelease(self);
ignoreRelease = NO;
}
- (void)release
{
[self dealloc];
}
- (void)drain
{
[self dealloc];
}
- (void)dealloc
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif
if (ignoreRelease)
return;
ignoreRelease = YES;
objc_autoreleasePoolPop(pool);
if (cache == NULL) {
cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
if (!of_tlskey_set(cacheKey, cache)) {
free(cache);
cache = NULL;
}
#endif
}
if (cache != NULL) {
unsigned i;
for (i = 0; i < MAX_CACHE_SIZE; i++) {
if (cache[i] == NULL) {
pool = NULL;
ignoreRelease = NO;
cache[i] = self;
return;
}
}
}
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
}
- init
{
self = [super init];
@try {
_pool = objc_autoreleasePoolPush();
_objc_rootAutorelease(self);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)releaseObjects
{
_ignoreRelease = YES;
objc_autoreleasePoolPop(_pool);
_pool = objc_autoreleasePoolPush();
_objc_rootAutorelease(self);
_ignoreRelease = NO;
}
- (void)release
{
[self dealloc];
}
- (void)drain
{
[self dealloc];
}
- (void)dealloc
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OFAutoreleasePool **cache = of_tlskey_get(cacheKey);
#endif
if (_ignoreRelease)
return;
_ignoreRelease = YES;
objc_autoreleasePoolPop(_pool);
if (cache == NULL) {
cache = calloc(sizeof(OFAutoreleasePool*), MAX_CACHE_SIZE);
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
if (!of_tlskey_set(cacheKey, cache)) {
free(cache);
cache = NULL;
}
#endif
}
if (cache != NULL) {
unsigned i;
for (i = 0; i < MAX_CACHE_SIZE; i++) {
if (cache[i] == NULL) {
_pool = NULL;
_ignoreRelease = NO;
cache[i] = self;
return;
}
}
}
|
︙ | | | ︙ | |
Modified src/OFCondition.h
from [5908f93915]
to [c116d03373].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFMutex.h"
/*!
* @brief A class implementing a condition variable for thread synchronization.
*/
@interface OFCondition: OFMutex
{
of_condition_t condition;
BOOL conditionInitialized;
}
/*!
* @brief Creates a new condition.
*
* @return A new, autoreleased OFCondition
*/
|
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFMutex.h"
/*!
* @brief A class implementing a condition variable for thread synchronization.
*/
@interface OFCondition: OFMutex
{
of_condition_t _condition;
BOOL _conditionInitialized;
}
/*!
* @brief Creates a new condition.
*
* @return A new, autoreleased OFCondition
*/
|
︙ | | | ︙ | |
Modified src/OFCondition.m
from [5df1aa0315]
to [7c4793cfc9].
︙ | | | ︙ | |
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_condition_new(&condition)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
conditionInitialized = YES;
return self;
}
- (void)wait
{
if (!of_condition_wait(&condition, &mutex))
@throw [OFConditionWaitFailedException
exceptionWithClass: [self class]
condition: self];
}
- (void)signal
{
if (!of_condition_signal(&condition))
@throw [OFConditionSignalFailedException
exceptionWithClass: [self class]
condition: self];
}
- (void)broadcast
{
if (!of_condition_broadcast(&condition))
@throw [OFConditionBroadcastFailedException
exceptionWithClass: [self class]
condition: self];
}
- (void)dealloc
{
if (conditionInitialized)
if (!of_condition_free(&condition))
@throw [OFConditionStillWaitingException
exceptionWithClass: [self class]
condition: self];
[super dealloc];
}
@end
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_condition_new(&_condition)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_conditionInitialized = YES;
return self;
}
- (void)dealloc
{
if (_conditionInitialized)
if (!of_condition_free(&_condition))
@throw [OFConditionStillWaitingException
exceptionWithClass: [self class]
condition: self];
[super dealloc];
}
- (void)wait
{
if (!of_condition_wait(&_condition, &_mutex))
@throw [OFConditionWaitFailedException
exceptionWithClass: [self class]
condition: self];
}
- (void)signal
{
if (!of_condition_signal(&_condition))
@throw [OFConditionSignalFailedException
exceptionWithClass: [self class]
condition: self];
}
- (void)broadcast
{
if (!of_condition_broadcast(&_condition))
@throw [OFConditionBroadcastFailedException
exceptionWithClass: [self class]
condition: self];
}
@end
|
Modified src/OFConstantString.h
from [a4e3964c53]
to [6b6b3d5b5b].
︙ | | | ︙ | |
28
29
30
31
32
33
34
35
36
37
38
|
#endif
/*!
* @brief A class for storing constant strings using the \@"" literal.
*/
@interface OFConstantString: OFString
{
char *cString;
size_t cStringLength;
}
@end
|
|
|
|
28
29
30
31
32
33
34
35
36
37
38
|
#endif
/*!
* @brief A class for storing constant strings using the \@"" literal.
*/
@interface OFConstantString: OFString
{
char *_cString;
size_t _cStringLength;
}
@end
|
Modified src/OFConstantString.m
from [02f6ef3191]
to [1a105f7a00].
︙ | | | ︙ | |
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
size: (size_t)size
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void*)resizeMemory: (void*)ptr
toNItems: (size_t)nitems
withSize: (size_t)size
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)freeMemory: (void*)ptr
{
|
|
|
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
size: (size_t)size
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void*)resizeMemory: (void*)ptr
size: (size_t)nitems
count: (size_t)size
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)freeMemory: (void*)ptr
{
|
︙ | | | ︙ | |
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
struct of_string_utf8_ivars *ivars;
if ((ivars = calloc(1, sizeof(*ivars))) == NULL)
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: sizeof(*ivars)];
ivars->cString = cString;
ivars->cStringLength = cStringLength;
switch (of_string_utf8_check(ivars->cString, ivars->cStringLength,
&ivars->length)) {
case 1:
ivars->isUTF8 = YES;
break;
case -1:
free(ivars);
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
cString = (char*)ivars;
object_setClass(self, [OFString_const class]);
}
+ alloc
{
[self doesNotRecognizeSelector: _cmd];
abort();
|
|
|
|
|
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
struct of_string_utf8_ivars *ivars;
if ((ivars = calloc(1, sizeof(*ivars))) == NULL)
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: sizeof(*ivars)];
ivars->cString = _cString;
ivars->cStringLength = _cStringLength;
switch (of_string_utf8_check(ivars->cString, ivars->cStringLength,
&ivars->length)) {
case 1:
ivars->isUTF8 = YES;
break;
case -1:
free(ivars);
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
_cString = (char*)ivars;
object_setClass(self, [OFString_const class]);
}
+ alloc
{
[self doesNotRecognizeSelector: _cmd];
abort();
|
︙ | | | ︙ | |
Modified src/OFCountedSet_hashtable.h
from [f3fb841536]
to [9946a99cd2].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
|
#import "OFCountedSet.h"
@class OFMapTable;
@interface OFCountedSet_hashtable: OFCountedSet
{
OFMapTable *mapTable;
}
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
|
#import "OFCountedSet.h"
@class OFMapTable;
@interface OFCountedSet_hashtable: OFCountedSet
{
OFMapTable *_mapTable;
}
@end
|
Modified src/OFCountedSet_hashtable.m
from [23039ce7da]
to [1c8a9015a1].
︙ | | | ︙ | |
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
if (object == nil || count_ == nil)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
count = (size_t)[[count_ stringValue] decimalValue];
[mapTable setValue: (void*)(uintptr_t)count
forKey: [object objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (size_t)countForObject: (id)object
{
return (size_t)(uintptr_t)[mapTable valueForKey: object];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsAndCountUsingBlock:
(of_counted_set_enumeration_block_t)block
{
@try {
[mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, (size_t)(uintptr_t)value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
- (void)addObject: (id)object
{
size_t count = (size_t)(uintptr_t)[mapTable valueForKey: object];
if (SIZE_MAX - count < 1)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
[mapTable setValue: (void*)(uintptr_t)(count + 1)
forKey: object];
}
- (void)removeObject: (id)object
{
size_t count = (size_t)(uintptr_t)[mapTable valueForKey: object];
if (count == 0)
return;
count--;
if (count > 0)
[mapTable setValue: (void*)(uintptr_t)count
forKey: object];
else
[mapTable removeValueForKey: object];
}
- (void)makeImmutable
{
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
if (object == nil || count_ == nil)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
count = (size_t)[[count_ stringValue] decimalValue];
[_mapTable setValue: (void*)(uintptr_t)count
forKey: [object objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (size_t)countForObject: (id)object
{
return (size_t)(uintptr_t)[_mapTable valueForKey: object];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsAndCountUsingBlock:
(of_counted_set_enumeration_block_t)block
{
@try {
[_mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, (size_t)(uintptr_t)value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
- (void)addObject: (id)object
{
size_t count = (size_t)(uintptr_t)[_mapTable valueForKey: object];
if (SIZE_MAX - count < 1)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
[_mapTable setValue: (void*)(uintptr_t)(count + 1)
forKey: object];
}
- (void)removeObject: (id)object
{
size_t count = (size_t)(uintptr_t)[_mapTable valueForKey: object];
if (count == 0)
return;
count--;
if (count > 0)
[_mapTable setValue: (void*)(uintptr_t)count
forKey: object];
else
[_mapTable removeValueForKey: object];
}
- (void)makeImmutable
{
}
@end
|
Modified src/OFDataArray+Hashing.m
from [681c8a7ef5]
to [2171c1b800].
︙ | | | ︙ | |
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
{
void *pool = objc_autoreleasePoolPush();
OFMD5Hash *hash = [OFMD5Hash hash];
uint8_t *digest;
char cString[OF_MD5_DIGEST_SIZE * 2];
size_t i;
[hash updateWithBuffer: items
length: count * itemSize];
digest = [hash digest];
for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) {
uint8_t high, low;
high = digest[i] >> 4;
low = digest[i] & 0x0F;
|
|
|
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
{
void *pool = objc_autoreleasePoolPush();
OFMD5Hash *hash = [OFMD5Hash hash];
uint8_t *digest;
char cString[OF_MD5_DIGEST_SIZE * 2];
size_t i;
[hash updateWithBuffer: _items
length: _count * _itemSize];
digest = [hash digest];
for (i = 0; i < OF_MD5_DIGEST_SIZE; i++) {
uint8_t high, low;
high = digest[i] >> 4;
low = digest[i] & 0x0F;
|
︙ | | | ︙ | |
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
{
void *pool = objc_autoreleasePoolPush();
OFSHA1Hash *hash = [OFSHA1Hash hash];
uint8_t *digest;
char cString[OF_SHA1_DIGEST_SIZE * 2];
size_t i;
[hash updateWithBuffer: items
length: count * itemSize];
digest = [hash digest];
for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) {
uint8_t high, low;
high = digest[i] >> 4;
low = digest[i] & 0x0F;
|
|
|
|
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
{
void *pool = objc_autoreleasePoolPush();
OFSHA1Hash *hash = [OFSHA1Hash hash];
uint8_t *digest;
char cString[OF_SHA1_DIGEST_SIZE * 2];
size_t i;
[hash updateWithBuffer: _items
length: _count * _itemSize];
digest = [hash digest];
for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++) {
uint8_t high, low;
high = digest[i] >> 4;
low = digest[i] & 0x0F;
|
︙ | | | ︙ | |
Modified src/OFDataArray.h
from [6f4ab00da5]
to [ccf132759c].
︙ | | | ︙ | |
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
* OFBigDataArray, which allocates the memory in pages rather than in bytes.
*
* For security reasons, serialization and deserialization is only implemented
* for OFDataArrays with item size 1.
*/
@interface OFDataArray: OFObject <OFCopying, OFComparing, OFSerialization>
{
uint8_t *items;
size_t count;
size_t itemSize;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *items;
@property (readonly) size_t count;
@property (readonly) size_t itemSize;
#endif
|
|
|
|
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
* OFBigDataArray, which allocates the memory in pages rather than in bytes.
*
* For security reasons, serialization and deserialization is only implemented
* for OFDataArrays with item size 1.
*/
@interface OFDataArray: OFObject <OFCopying, OFComparing, OFSerialization>
{
uint8_t *_items;
size_t _count;
size_t _itemSize;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *items;
@property (readonly) size_t count;
@property (readonly) size_t itemSize;
#endif
|
︙ | | | ︙ | |
274
275
276
277
278
279
280
281
282
283
284
285
|
*
* The OFBigDataArray class is a class for storing arbitrary data in an array
* and is designed to store large hunks of data. Therefore, it allocates
* memory in pages rather than a chunk of memory for each item.
*/
@interface OFBigDataArray: OFDataArray
{
size_t size;
}
@end
#import "OFDataArray+Hashing.h"
|
|
|
274
275
276
277
278
279
280
281
282
283
284
285
|
*
* The OFBigDataArray class is a class for storing arbitrary data in an array
* and is designed to store large hunks of data. Therefore, it allocates
* memory in pages rather than a chunk of memory for each item.
*/
@interface OFBigDataArray: OFDataArray
{
size_t _size;
}
@end
#import "OFDataArray+Hashing.h"
|
Modified src/OFDataArray.m
from [993787fe25]
to [85eaead6fd].
︙ | | | ︙ | |
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
119
120
121
122
123
|
return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}
- init
{
self = [super init];
itemSize = 1;
return self;
}
- initWithItemSize: (size_t)itemSize_
{
self = [super init];
if (itemSize_ == 0) {
Class c = [self class];
[self release];
@throw [OFInvalidArgumentException exceptionWithClass: c
selector: _cmd];
}
itemSize = itemSize_;
return self;
}
- initWithContentsOfFile: (OFString*)path
{
self = [super init];
@try {
OFFile *file = [[OFFile alloc] initWithPath: path
mode: @"rb"];
itemSize = 1;
@try {
size_t pageSize = [OFSystemInfo pageSize];
char *buffer = [self allocMemoryWithSize: pageSize];
while (![file isAtEndOfStream]) {
size_t length;
|
|
|
|
|
|
|
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
119
120
121
122
123
|
return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}
- init
{
self = [super init];
_itemSize = 1;
return self;
}
- initWithItemSize: (size_t)itemSize
{
self = [super init];
if (itemSize == 0) {
Class c = [self class];
[self release];
@throw [OFInvalidArgumentException exceptionWithClass: c
selector: _cmd];
}
_itemSize = itemSize;
return self;
}
- initWithContentsOfFile: (OFString*)path
{
self = [super init];
@try {
OFFile *file = [[OFFile alloc] initWithPath: path
mode: @"rb"];
_itemSize = 1;
@try {
size_t pageSize = [OFSystemInfo pageSize];
char *buffer = [self allocMemoryWithSize: pageSize];
while (![file isAtEndOfStream]) {
size_t length;
|
︙ | | | ︙ | |
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
{
self = [super init];
@try {
const char *cString;
size_t i;
itemSize = 1;
count = [string
cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII];
if (count & 1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
count >>= 1;
cString = [string
cStringWithEncoding: OF_STRING_ENCODING_ASCII];
items = [self allocMemoryWithSize: count];
for (i = 0; i < count; i++) {
uint8_t c1 = cString[2 * i];
uint8_t c2 = cString[2 * i + 1];
uint8_t byte;
if (c1 >= '0' && c1 <= '9')
byte = (c1 - '0') << 4;
else if (c1 >= 'a' && c1 <= 'f')
|
|
|
|
|
|
|
|
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
{
self = [super init];
@try {
const char *cString;
size_t i;
_itemSize = 1;
_count = [string
cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII];
if (_count & 1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_count >>= 1;
cString = [string
cStringWithEncoding: OF_STRING_ENCODING_ASCII];
_items = [self allocMemoryWithSize: _count];
for (i = 0; i < _count; i++) {
uint8_t c1 = cString[2 * i];
uint8_t c2 = cString[2 * i + 1];
uint8_t byte;
if (c1 >= '0' && c1 <= '9')
byte = (c1 - '0') << 4;
else if (c1 >= 'a' && c1 <= 'f')
|
︙ | | | ︙ | |
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
byte |= c2 - 'a' + 10;
else if (c2 >= 'A' && c2 <= 'F')
byte |= c2 - 'A' + 10;
else
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
items[i] = byte;
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithBase64EncodedString: (OFString*)string
{
self = [super init];
@try {
itemSize = 1;
if (!of_base64_decode(self, [string cStringWithEncoding:
OF_STRING_ENCODING_ASCII], [string
cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) {
Class c = [self class];
[self release];
@throw [OFInvalidFormatException exceptionWithClass: c];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithSerialization: (OFXMLElement*)element
{
self = [super init];
itemSize = 1;
@try {
void *pool = objc_autoreleasePoolPush();
OFString *stringValue;
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
|
|
|
|
|
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
byte |= c2 - 'a' + 10;
else if (c2 >= 'A' && c2 <= 'F')
byte |= c2 - 'A' + 10;
else
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_items[i] = byte;
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithBase64EncodedString: (OFString*)string
{
self = [super init];
@try {
_itemSize = 1;
if (!of_base64_decode(self, [string cStringWithEncoding:
OF_STRING_ENCODING_ASCII], [string
cStringLengthWithEncoding: OF_STRING_ENCODING_ASCII])) {
Class c = [self class];
[self release];
@throw [OFInvalidFormatException exceptionWithClass: c];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithSerialization: (OFXMLElement*)element
{
self = [super init];
_itemSize = 1;
@try {
void *pool = objc_autoreleasePoolPush();
OFString *stringValue;
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
|
︙ | | | ︙ | |
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
|
}
return self;
}
- (size_t)count
{
return count;
}
- (size_t)itemSize
{
return itemSize;
}
- (void*)items
{
return items;
}
- (void*)itemAtIndex: (size_t)index
{
if (index >= count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return items + index * itemSize;
}
- (void*)firstItem
{
if (items == NULL || count == 0)
return NULL;
return items;
}
- (void*)lastItem
{
if (items == NULL || count == 0)
return NULL;
return items + (count - 1) * itemSize;
}
- (void)addItem: (const void*)item
{
if (SIZE_MAX - count < 1)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
items = [self resizeMemory: items
size: itemSize
count: count + 1];
memcpy(items + count * itemSize, item, itemSize);
count++;
}
- (void)insertItem: (const void*)item
atIndex: (size_t)index
{
[self insertItems: item
atIndex: index
count: 1];
}
- (void)addItems: (const void*)items_
count: (size_t)count_
{
if (count_ > SIZE_MAX - count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
items = [self resizeMemory: items
size: itemSize
count: count + count_];
memcpy(items + count * itemSize, items_, count_ * itemSize);
count += count_;
}
- (void)insertItems: (const void*)items_
atIndex: (size_t)index
count: (size_t)count_
{
if (count_ > SIZE_MAX - count || index > count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
items = [self resizeMemory: items
size: itemSize
count: count + count_];
memmove(items + (index + count_) * itemSize, items + index * itemSize,
(count - index) * itemSize);
memcpy(items + index * itemSize, items_, count_ * itemSize);
count += count_;
}
- (void)removeItemAtIndex: (size_t)index
{
[self removeItemsInRange: of_range(index, 1)];
}
- (void)removeItemsInRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memmove(items + range.location * itemSize,
items + (range.location + range.length) * itemSize,
(count - range.location - range.length) * itemSize);
count -= range.length;
@try {
items = [self resizeMemory: items
size: itemSize
count: count];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)removeLastItem
{
if (count == 0)
return;
count--;
@try {
items = [self resizeMemory: items
size: itemSize
count: count];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
}
- (void)removeAllItems
{
[self freeMemory: items];
items = NULL;
count = 0;
}
- copy
{
OFDataArray *copy = [[[self class] alloc] initWithItemSize: itemSize];
[copy addItems: items
count: count];
return copy;
}
- (BOOL)isEqual: (id)object
{
OFDataArray *otherDataArray;
if (![object isKindOfClass: [OFDataArray class]])
return NO;
otherDataArray = object;
if ([otherDataArray count] != count ||
[otherDataArray itemSize] != itemSize)
return NO;
if (memcmp([otherDataArray items], items, count * itemSize))
return NO;
return YES;
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
OFDataArray *otherDataArray;
int comparison;
size_t otherCount, minimumCount;
if (![object isKindOfClass: [OFDataArray class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherDataArray = (OFDataArray*)object;
if ([otherDataArray itemSize] != itemSize)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherCount = [otherDataArray count];
minimumCount = (count > otherCount ? otherCount : count);
if ((comparison = memcmp(items, [otherDataArray items],
minimumCount * itemSize)) == 0) {
if (count > otherCount)
return OF_ORDERED_DESCENDING;
if (count < otherCount)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (comparison > 0)
return OF_ORDERED_DESCENDING;
else
return OF_ORDERED_ASCENDING;
}
- (uint32_t)hash
{
uint32_t hash;
size_t i;
OF_HASH_INIT(hash);
for (i = 0; i < count * itemSize; i++)
OF_HASH_ADD(hash, ((uint8_t*)items)[i]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFString*)description
{
OFMutableString *ret = [OFMutableString stringWithString: @"<"];
size_t i;
for (i = 0; i < count; i++) {
size_t j;
if (i > 0)
[ret appendString: @" "];
for (j = 0; j < itemSize; j++)
[ret appendFormat: @"%02x", items[i * itemSize + j]];
}
[ret appendString: @">"];
[ret makeImmutable];
return ret;
}
- (OFString*)stringRepresentation
{
OFMutableString *ret = [OFMutableString string];
size_t i, j;
for (i = 0; i < count; i++)
for (j = 0; j < itemSize; j++)
[ret appendFormat: @"%02x", items[i * itemSize + j]];
[ret makeImmutable];
return ret;
}
- (OFString*)stringByBase64Encoding
{
return of_base64_encode(items, count * itemSize);
}
- (void)writeToFile: (OFString*)path
{
OFFile *file = [[OFFile alloc] initWithPath: path
mode: @"wb"];
@try {
[file writeBuffer: items
length: count * itemSize];
} @finally {
[file release];
}
}
- (OFXMLElement*)XMLElementBySerializing
{
void *pool;
OFXMLElement *element;
if (itemSize != 1)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
pool = objc_autoreleasePoolPush();
element = [OFXMLElement
elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: of_base64_encode(items, count * itemSize)];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
@end
@implementation OFBigDataArray
- (void)addItem: (const void*)item
{
size_t newSize, lastPageByte;
if (SIZE_MAX - count < 1 || count + 1 > SIZE_MAX / itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
newSize = ((count + 1) * itemSize + lastPageByte) & ~lastPageByte;
if (size != newSize)
items = [self resizeMemory: items
size: newSize];
memcpy(items + count * itemSize, item, itemSize);
count++;
size = newSize;
}
- (void)addItems: (const void*)items_
count: (size_t)count_
{
size_t newSize, lastPageByte;
if (count_ > SIZE_MAX - count || count + count_ > SIZE_MAX / itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;
if (size != newSize)
items = [self resizeMemory: items
size: newSize];
memcpy(items + count * itemSize, items_, count_ * itemSize);
count += count_;
size = newSize;
}
- (void)insertItems: (const void*)items_
atIndex: (size_t)index
count: (size_t)count_
{
size_t newSize, lastPageByte;
if (count_ > SIZE_MAX - count || index > count ||
count + count_ > SIZE_MAX / itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
newSize = ((count + count_) * itemSize + lastPageByte) & ~lastPageByte;
if (size != newSize)
items = [self resizeMemory: items
size: newSize];
memmove(items + (index + count_) * itemSize, items + index * itemSize,
(count - index) * itemSize);
memcpy(items + index * itemSize, items_, count_ * itemSize);
count += count_;
size = newSize;
}
- (void)removeItemsInRange: (of_range_t)range
{
size_t pageSize, newSize;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memmove(items + range.location * itemSize,
items + (range.location + range.length) * itemSize,
(count - range.location - range.length) * itemSize);
count -= range.length;
pageSize = [OFSystemInfo pageSize];
newSize = (count * itemSize + pageSize - 1) & ~(pageSize - 1);
if (size != newSize && newSize >= pageSize) {
@try {
items = [self resizeMemory: items
size: newSize];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
size = newSize;
}
}
- (void)removeLastItem
{
size_t pageSize, newSize;
if (count == 0)
return;
count--;
pageSize = [OFSystemInfo pageSize];
newSize = (count * itemSize + pageSize - 1) & ~(pageSize - 1);
if (size != newSize && newSize >= pageSize) {
@try {
items = [self resizeMemory: items
size: newSize];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
size = newSize;
}
}
- (void)removeAllItems
{
size_t pageSize = [OFSystemInfo pageSize];
@try {
items = [self resizeMemory: items
size: pageSize];
size = pageSize;
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
count = 0;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
|
}
return self;
}
- (size_t)count
{
return _count;
}
- (size_t)itemSize
{
return _itemSize;
}
- (void*)items
{
return _items;
}
- (void*)itemAtIndex: (size_t)index
{
if (index >= _count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return _items + index * _itemSize;
}
- (void*)firstItem
{
if (_items == NULL || _count == 0)
return NULL;
return _items;
}
- (void*)lastItem
{
if (_items == NULL || _count == 0)
return NULL;
return _items + (_count - 1) * _itemSize;
}
- (void)addItem: (const void*)item
{
if (SIZE_MAX - _count < 1)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
_items = [self resizeMemory: _items
size: _itemSize
count: _count + 1];
memcpy(_items + _count * _itemSize, item, _itemSize);
_count++;
}
- (void)insertItem: (const void*)item
atIndex: (size_t)index
{
[self insertItems: item
atIndex: index
count: 1];
}
- (void)addItems: (const void*)items
count: (size_t)count
{
if (count > SIZE_MAX - count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
_items = [self resizeMemory: _items
size: _itemSize
count: _count + count];
memcpy(_items + _count * _itemSize, items, count * _itemSize);
_count += count;
}
- (void)insertItems: (const void*)items
atIndex: (size_t)index
count: (size_t)count
{
if (count > SIZE_MAX - _count || index > _count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
_items = [self resizeMemory: _items
size: _itemSize
count: _count + count];
memmove(_items + (index + count) * _itemSize,
_items + index * _itemSize, (_count - index) * _itemSize);
memcpy(_items + index * _itemSize, items, count * _itemSize);
_count += count;
}
- (void)removeItemAtIndex: (size_t)index
{
[self removeItemsInRange: of_range(index, 1)];
}
- (void)removeItemsInRange: (of_range_t)range
{
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memmove(_items + range.location * _itemSize,
_items + (range.location + range.length) * _itemSize,
(_count - range.location - range.length) * _itemSize);
_count -= range.length;
@try {
_items = [self resizeMemory: _items
size: _itemSize
count: _count];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)removeLastItem
{
if (_count == 0)
return;
_count--;
@try {
_items = [self resizeMemory: _items
size: _itemSize
count: _count];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
}
- (void)removeAllItems
{
[self freeMemory: _items];
_items = NULL;
_count = 0;
}
- copy
{
OFDataArray *copy = [[[self class] alloc] initWithItemSize: _itemSize];
[copy addItems: _items
count: _count];
return copy;
}
- (BOOL)isEqual: (id)object
{
OFDataArray *dataArray;
if (![object isKindOfClass: [OFDataArray class]])
return NO;
dataArray = object;
if ([dataArray count] != _count ||
[dataArray itemSize] != _itemSize)
return NO;
if (memcmp([dataArray items], _items, _count * _itemSize))
return NO;
return YES;
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
OFDataArray *dataArray;
int comparison;
size_t count, minCount;
if (![object isKindOfClass: [OFDataArray class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
dataArray = (OFDataArray*)object;
if ([dataArray itemSize] != _itemSize)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
count = [dataArray count];
minCount = (_count > count ? count : _count);
if ((comparison = memcmp(_items, [dataArray items],
minCount * _itemSize)) == 0) {
if (_count > count)
return OF_ORDERED_DESCENDING;
if (_count < count)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (comparison > 0)
return OF_ORDERED_DESCENDING;
else
return OF_ORDERED_ASCENDING;
}
- (uint32_t)hash
{
uint32_t hash;
size_t i;
OF_HASH_INIT(hash);
for (i = 0; i < _count * _itemSize; i++)
OF_HASH_ADD(hash, ((uint8_t*)_items)[i]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFString*)description
{
OFMutableString *ret = [OFMutableString stringWithString: @"<"];
size_t i;
for (i = 0; i < _count; i++) {
size_t j;
if (i > 0)
[ret appendString: @" "];
for (j = 0; j < _itemSize; j++)
[ret appendFormat: @"%02x", _items[i * _itemSize + j]];
}
[ret appendString: @">"];
[ret makeImmutable];
return ret;
}
- (OFString*)stringRepresentation
{
OFMutableString *ret = [OFMutableString string];
size_t i, j;
for (i = 0; i < _count; i++)
for (j = 0; j < _itemSize; j++)
[ret appendFormat: @"%02x", _items[i * _itemSize + j]];
[ret makeImmutable];
return ret;
}
- (OFString*)stringByBase64Encoding
{
return of_base64_encode(_items, _count * _itemSize);
}
- (void)writeToFile: (OFString*)path
{
OFFile *file = [[OFFile alloc] initWithPath: path
mode: @"wb"];
@try {
[file writeBuffer: _items
length: _count * _itemSize];
} @finally {
[file release];
}
}
- (OFXMLElement*)XMLElementBySerializing
{
void *pool;
OFXMLElement *element;
if (_itemSize != 1)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
pool = objc_autoreleasePoolPush();
element = [OFXMLElement
elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: of_base64_encode(_items, _count * _itemSize)];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
@end
@implementation OFBigDataArray
- (void)addItem: (const void*)item
{
size_t size, lastPageByte;
if (SIZE_MAX - _count < 1 || _count + 1 > SIZE_MAX / _itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
size = ((_count + 1) * _itemSize + lastPageByte) & ~lastPageByte;
if (_size != size)
_items = [self resizeMemory: _items
size: size];
memcpy(_items + _count * _itemSize, item, _itemSize);
_count++;
_size = size;
}
- (void)addItems: (const void*)items
count: (size_t)count
{
size_t size, lastPageByte;
if (count > SIZE_MAX - _count || _count + count > SIZE_MAX / _itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;
if (_size != size)
_items = [self resizeMemory: _items
size: size];
memcpy(_items + _count * _itemSize, items, count * _itemSize);
_count += count;
_size = size;
}
- (void)insertItems: (const void*)items
atIndex: (size_t)index
count: (size_t)count
{
size_t size, lastPageByte;
if (count > SIZE_MAX - _count || index > _count ||
_count + count > SIZE_MAX / _itemSize)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
lastPageByte = [OFSystemInfo pageSize] - 1;
size = ((_count + count) * _itemSize + lastPageByte) & ~lastPageByte;
if (_size != size)
_items = [self resizeMemory: _items
size: size];
memmove(_items + (index + count) * _itemSize,
_items + index * _itemSize, (_count - index) * _itemSize);
memcpy(_items + index * _itemSize, items, count * _itemSize);
_count += count;
_size = size;
}
- (void)removeItemsInRange: (of_range_t)range
{
size_t pageSize, size;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memmove(_items + range.location * _itemSize,
_items + (range.location + range.length) * _itemSize,
(_count - range.location - range.length) * _itemSize);
_count -= range.length;
pageSize = [OFSystemInfo pageSize];
size = (_count * _itemSize + pageSize - 1) & ~(pageSize - 1);
if (_size != size && size >= pageSize) {
@try {
_items = [self resizeMemory: _items
size: size];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
_size = size;
}
}
- (void)removeLastItem
{
size_t pageSize, size;
if (_count == 0)
return;
_count--;
pageSize = [OFSystemInfo pageSize];
size = (_count * _itemSize + pageSize - 1) & ~(pageSize - 1);
if (_size != size && size >= pageSize) {
@try {
_items = [self resizeMemory: _items
size: size];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
_size = size;
}
}
- (void)removeAllItems
{
size_t pageSize = [OFSystemInfo pageSize];
@try {
_items = [self resizeMemory: _items
size: pageSize];
_size = pageSize;
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only made it smaller */
}
_count = 0;
}
@end
|
Modified src/OFDate.h
from [ba694484be]
to [fe89bdb0e0].
︙ | | | ︙ | |
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFConstantString;
/*!
* @brief A class for storing, accessing and comparing dates.
*/
@interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization>
{
double seconds;
}
/*!
* @brief Creates a new OFDate with the current date and time.
*
* @return A new, autoreleased OFDate with the current date and time
*/
|
|
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFConstantString;
/*!
* @brief A class for storing, accessing and comparing dates.
*/
@interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization>
{
double _seconds;
}
/*!
* @brief Creates a new OFDate with the current date and time.
*
* @return A new, autoreleased OFDate with the current date and time
*/
|
︙ | | | ︙ | |
Modified src/OFDate.m
from [a29328b01b]
to [bc182cbf9d].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
defined(OF_HAVE_THREADS)
static OFMutex *mutex;
#endif
#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if (gmtime_r(&seconds_, &tm) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm.field;
# define LOCALTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if (localtime_r(&seconds_, &tm) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm.field;
#else
# ifdef OF_HAVE_THREADS
# define GMTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm *tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
[mutex lock]; \
\
@try { \
if ((tm = gmtime(&seconds_)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field; \
} @finally { \
[mutex unlock]; \
}
# define LOCALTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm *tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
[mutex lock]; \
\
@try { \
if ((tm = localtime(&seconds_)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field; \
} @finally { \
[mutex unlock]; \
}
# else
# define GMTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm *tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if ((tm = gmtime(&seconds_)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field;
# define LOCALTIME_RET(field) \
time_t seconds_ = (time_t)seconds; \
struct tm *tm; \
\
if (seconds_ != floor(seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if ((tm = localtime(&seconds_)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field;
# endif
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \
defined(OF_HAVE_THREADS)
static OFMutex *mutex;
#endif
#ifdef HAVE_GMTIME_R
# define GMTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if (gmtime_r(&seconds, &tm) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm.field;
# define LOCALTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if (localtime_r(&seconds, &tm) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm.field;
#else
# ifdef OF_HAVE_THREADS
# define GMTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm *tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
[mutex lock]; \
\
@try { \
if ((tm = gmtime(&seconds)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field; \
} @finally { \
[mutex unlock]; \
}
# define LOCALTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm *tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
[mutex lock]; \
\
@try { \
if ((tm = localtime(&seconds)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field; \
} @finally { \
[mutex unlock]; \
}
# else
# define GMTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm *tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if ((tm = gmtime(&seconds)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field;
# define LOCALTIME_RET(field) \
time_t seconds = (time_t)_seconds; \
struct tm *tm; \
\
if (seconds != floor(_seconds)) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
if ((tm = localtime(&seconds)) == NULL) \
@throw [OFOutOfRangeException \
exceptionWithClass: [self class]]; \
\
return tm->field;
# endif
#endif
|
︙ | | | ︙ | |
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
- init
{
struct timeval t;
self = [super init];
OF_ENSURE(!gettimeofday(&t, NULL));
seconds = t.tv_sec;
seconds += (double)t.tv_usec / 1000000;
return self;
}
- initWithTimeIntervalSince1970: (double)seconds_
{
self = [super init];
seconds = seconds_;
return self;
}
- initWithTimeIntervalSinceNow: (double)seconds_
{
self = [self init];
seconds += seconds_;
return self;
}
- initWithDateString: (OFString*)string
format: (OFString*)format
{
self = [super init];
@try {
struct tm tm = {};
tm.tm_isdst = -1;
if (of_strptime([string UTF8String], [format UTF8String],
&tm) == NULL)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
/* Years */
seconds = (int64_t)(tm.tm_year - 70) * 31536000;
/* Days of leap years, excluding the year to look at */
seconds += (((tm.tm_year + 1899) / 4) - 492) * 86400;
seconds -= (((tm.tm_year + 1899) / 100) - 19) * 86400;
seconds += (((tm.tm_year + 1899) / 400) - 4) * 86400;
/* Leap day */
if (tm.tm_mon >= 2 && (((tm.tm_year + 1900) % 4 == 0 &&
(tm.tm_year + 1900) % 100 != 0) ||
(tm.tm_year + 1900) % 400 == 0))
seconds += 86400;
/* Months */
if (tm.tm_mon < 0 || tm.tm_mon > 12)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
seconds += month_to_day_of_year[tm.tm_mon] * 86400;
/* Days */
seconds += (tm.tm_mday - 1) * 86400;
/* Hours */
seconds += tm.tm_hour * 3600;
/* Minutes */
seconds += tm.tm_min * 60;
/* Seconds */
seconds += tm.tm_sec;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
- init
{
struct timeval t;
self = [super init];
OF_ENSURE(gettimeofday(&t, NULL) == 0);
_seconds = t.tv_sec;
_seconds += (double)t.tv_usec / 1000000;
return self;
}
- initWithTimeIntervalSince1970: (double)seconds
{
self = [super init];
_seconds = seconds;
return self;
}
- initWithTimeIntervalSinceNow: (double)seconds
{
self = [self init];
_seconds += seconds;
return self;
}
- initWithDateString: (OFString*)string
format: (OFString*)format
{
self = [super init];
@try {
struct tm tm = {};
tm.tm_isdst = -1;
if (of_strptime([string UTF8String], [format UTF8String],
&tm) == NULL)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
/* Years */
_seconds = (int64_t)(tm.tm_year - 70) * 31536000;
/* Days of leap years, excluding the year to look at */
_seconds += (((tm.tm_year + 1899) / 4) - 492) * 86400;
_seconds -= (((tm.tm_year + 1899) / 100) - 19) * 86400;
_seconds += (((tm.tm_year + 1899) / 400) - 4) * 86400;
/* Leap day */
if (tm.tm_mon >= 2 && (((tm.tm_year + 1900) % 4 == 0 &&
(tm.tm_year + 1900) % 100 != 0) ||
(tm.tm_year + 1900) % 400 == 0))
_seconds += 86400;
/* Months */
if (tm.tm_mon < 0 || tm.tm_mon > 12)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_seconds += month_to_day_of_year[tm.tm_mon] * 86400;
/* Days */
_seconds += (tm.tm_mday - 1) * 86400;
/* Hours */
_seconds += tm.tm_hour * 3600;
/* Minutes */
_seconds += tm.tm_min * 60;
/* Seconds */
_seconds += tm.tm_sec;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
tm.tm_isdst = -1;
if (of_strptime([string UTF8String], [format UTF8String],
&tm) == NULL)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
if ((seconds = mktime(&tm)) == -1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
tm.tm_isdst = -1;
if (of_strptime([string UTF8String], [format UTF8String],
&tm) == NULL)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
if ((_seconds = mktime(&tm)) == -1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
d.u = (uint64_t)[element hexadecimalValue];
seconds = d.d;
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFDate *otherDate;
if (![object isKindOfClass: [OFDate class]])
return NO;
otherDate = object;
if (otherDate->seconds != seconds)
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
union {
double d;
uint8_t b[sizeof(double)];
} d;
uint_fast8_t i;
d.d = OF_BSWAP_DOUBLE_IF_BE(seconds);
OF_HASH_INIT(hash);
for (i = 0; i < sizeof(double); i++)
OF_HASH_ADD(hash, d.b[i]);
OF_HASH_FINALIZE(hash);
|
|
|
|
|
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
d.u = (uint64_t)[element hexadecimalValue];
_seconds = d.d;
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFDate *otherDate;
if (![object isKindOfClass: [OFDate class]])
return NO;
otherDate = object;
if (otherDate->_seconds != _seconds)
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
union {
double d;
uint8_t b[sizeof(double)];
} d;
uint_fast8_t i;
d.d = OF_BSWAP_DOUBLE_IF_BE(_seconds);
OF_HASH_INIT(hash);
for (i = 0; i < sizeof(double); i++)
OF_HASH_ADD(hash, d.b[i]);
OF_HASH_FINALIZE(hash);
|
︙ | | | ︙ | |
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
|
if (![object isKindOfClass: [OFDate class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherDate = (OFDate*)object;
if (seconds < otherDate->seconds)
return OF_ORDERED_ASCENDING;
if (seconds > otherDate->seconds)
return OF_ORDERED_DESCENDING;
return OF_ORDERED_SAME;
}
- (OFString*)description
{
|
|
|
|
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
|
if (![object isKindOfClass: [OFDate class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherDate = (OFDate*)object;
if (_seconds < otherDate->_seconds)
return OF_ORDERED_ASCENDING;
if (_seconds > otherDate->_seconds)
return OF_ORDERED_DESCENDING;
return OF_ORDERED_SAME;
}
- (OFString*)description
{
|
︙ | | | ︙ | |
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
|
double d;
uint64_t u;
} d;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
d.d = seconds;
[element setStringValue:
[OFString stringWithFormat: @"%016" PRIx64, d.u]];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (uint32_t)microsecond
{
return (uint32_t)rint((seconds - floor(seconds)) * 1000000);
}
- (uint8_t)second
{
GMTIME_RET(tm_sec)
}
|
|
|
|
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
|
double d;
uint64_t u;
} d;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
d.d = _seconds;
[element setStringValue:
[OFString stringWithFormat: @"%016" PRIx64, d.u]];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (uint32_t)microsecond
{
return (uint32_t)rint((_seconds - floor(_seconds)) * 1000000);
}
- (uint8_t)second
{
GMTIME_RET(tm_sec)
}
|
︙ | | | ︙ | |
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
|
{
LOCALTIME_RET(tm_yday + 1)
}
- (OFString*)dateStringWithFormat: (OFConstantString*)format
{
OFString *ret;
time_t seconds_ = (time_t)seconds;
struct tm tm;
size_t pageSize;
char *buffer;
if (seconds_ != floor(seconds))
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#ifdef HAVE_GMTIME_R
if (gmtime_r(&seconds_, &tm) == NULL)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
struct tm *tmp;
if ((tmp = gmtime(&seconds_)) == NULL)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
tm = *tmp;
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
|
|
|
|
|
|
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
|
{
LOCALTIME_RET(tm_yday + 1)
}
- (OFString*)dateStringWithFormat: (OFConstantString*)format
{
OFString *ret;
time_t seconds = (time_t)_seconds;
struct tm tm;
size_t pageSize;
char *buffer;
if (seconds != floor(_seconds))
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#ifdef HAVE_GMTIME_R
if (gmtime_r(&seconds, &tm) == NULL)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
struct tm *tmp;
if ((tmp = gmtime(&seconds)) == NULL)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
tm = *tmp;
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
|
︙ | | | ︙ | |
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
return ret;
}
- (OFString*)localDateStringWithFormat: (OFConstantString*)format
{
OFString *ret;
time_t seconds_ = (time_t)seconds;
struct tm tm;
size_t pageSize;
char *buffer;
if (seconds_ != floor(seconds))
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#ifdef HAVE_LOCALTIME_R
if (localtime_r(&seconds_, &tm) == NULL)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
struct tm *tmp;
if ((tmp = localtime(&seconds_)) == NULL)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
tm = *tmp;
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
|
|
|
|
|
|
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
return ret;
}
- (OFString*)localDateStringWithFormat: (OFConstantString*)format
{
OFString *ret;
time_t seconds = (time_t)_seconds;
struct tm tm;
size_t pageSize;
char *buffer;
if (seconds != floor(_seconds))
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#ifdef HAVE_LOCALTIME_R
if (localtime_r(&seconds, &tm) == NULL)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
struct tm *tmp;
if ((tmp = localtime(&seconds)) == NULL)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
tm = *tmp;
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
|
︙ | | | ︙ | |
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
|
return [[otherDate retain] autorelease];
return [[self retain] autorelease];
}
- (double)timeIntervalSince1970
{
return seconds;
}
- (double)timeIntervalSinceDate: (OFDate*)otherDate
{
return seconds - otherDate->seconds;
}
- (double)timeIntervalSinceNow
{
struct timeval t;
double seconds_;
OF_ENSURE(!gettimeofday(&t, NULL));
seconds_ = t.tv_sec;
seconds_ += (double)t.tv_usec / 1000000;
return seconds - seconds_;
}
- (OFDate*)dateByAddingTimeInterval: (double)seconds_
{
return [OFDate dateWithTimeIntervalSince1970: seconds + seconds_];
}
@end
|
|
|
|
|
|
|
|
|
|
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
|
return [[otherDate retain] autorelease];
return [[self retain] autorelease];
}
- (double)timeIntervalSince1970
{
return _seconds;
}
- (double)timeIntervalSinceDate: (OFDate*)otherDate
{
return _seconds - otherDate->_seconds;
}
- (double)timeIntervalSinceNow
{
struct timeval t;
double seconds;
OF_ENSURE(!gettimeofday(&t, NULL));
seconds = t.tv_sec;
seconds += (double)t.tv_usec / 1000000;
return _seconds - seconds;
}
- (OFDate*)dateByAddingTimeInterval: (double)seconds
{
return [OFDate dateWithTimeIntervalSince1970: _seconds + seconds];
}
@end
|
Modified src/OFDictionary_hashtable.h
from [3842e437d1]
to [9ac7ec716c].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
|
#import "OFDictionary.h"
@class OFMapTable;
@class OFMapTableEnumerator;
@interface OFDictionary_hashtable: OFDictionary
{
OFMapTable *mapTable;
}
- initWithCapacity: (size_t)capacity;
@end
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
|
#import "OFDictionary.h"
@class OFMapTable;
@class OFMapTableEnumerator;
@interface OFDictionary_hashtable: OFDictionary
{
OFMapTable *_mapTable;
}
- initWithCapacity: (size_t)capacity;
@end
|
Modified src/OFDictionary_hashtable.m
from [27697200eb]
to [6f8779fe47].
︙ | | | ︙ | |
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
}
- initWithCapacity: (size_t)capacity
{
self = [super init];
@try {
mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: capacity];
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
}
- initWithCapacity: (size_t)capacity
{
self = [super init];
@try {
_mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: capacity];
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
[dictionary class] == [OFMutableDictionary_hashtable class]) {
self = [super init];
@try {
OFDictionary_hashtable *dictionary_ =
(OFDictionary_hashtable*)dictionary;
mapTable = [dictionary_->mapTable copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
[dictionary class] == [OFMutableDictionary_hashtable class]) {
self = [super init];
@try {
OFDictionary_hashtable *dictionary_ =
(OFDictionary_hashtable*)dictionary;
_mapTable = [dictionary_->_mapTable copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
OFEnumerator *keyEnumerator, *objectEnumerator;
id key, object;
keyEnumerator = [dictionary keyEnumerator];
objectEnumerator = [dictionary objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[mapTable setValue: object
forKey: key];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)object
forKey: (id)key
{
self = [self initWithCapacity: 1];
@try {
[mapTable setValue: object
forKey: key];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObjects: (id const*)objects
forKeys: (id const*)keys
count: (size_t)count
{
self = [self initWithCapacity: count];
@try {
size_t i;
for (i = 0; i < count; i++)
[mapTable setValue: objects[i]
forKey: keys[i]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
OFEnumerator *keyEnumerator, *objectEnumerator;
id key, object;
keyEnumerator = [dictionary keyEnumerator];
objectEnumerator = [dictionary objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[_mapTable setValue: object
forKey: key];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObject: (id)object
forKey: (id)key
{
self = [self initWithCapacity: 1];
@try {
[_mapTable setValue: object
forKey: key];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObjects: (id const*)objects
forKeys: (id const*)keys
count: (size_t)count
{
self = [self initWithCapacity: count];
@try {
size_t i;
for (i = 0; i < count; i++)
[_mapTable setValue: objects[i]
forKey: keys[i]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
exceptionWithClass: [self class]
selector: _cmd];
count = 1;
for (; va_arg(argumentsCopy, id) != nil; count++);
count >>= 1;
mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: count];
[mapTable setValue: object
forKey: key];
for (i = 1; i < count; i++) {
key = va_arg(arguments, id);
object = va_arg(arguments, id);
if (key == nil || object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[mapTable setValue: object
forKey: key];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
|
|
|
|
|
|
|
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
exceptionWithClass: [self class]
selector: _cmd];
count = 1;
for (; va_arg(argumentsCopy, id) != nil; count++);
count >>= 1;
_mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: count];
[_mapTable setValue: object
forKey: key];
for (i = 1; i < count; i++) {
key = va_arg(arguments, id);
object = va_arg(arguments, id);
if (key == nil || object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[_mapTable setValue: object
forKey: key];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
|
︙ | | | ︙ | |
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
objects = [element elementsForName: @"object"
namespace: OF_SERIALIZATION_NS];
if ([keys count] != [objects count])
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: [keys count]];
keyEnumerator = [keys objectEnumerator];
objectEnumerator = [objects objectEnumerator];
while ((keyElement = [keyEnumerator nextObject]) != nil &&
(objectElement = [objectEnumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
OFXMLElement *key, *object;
key = [[keyElement elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
object = [[objectElement elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
if (key == nil || object == nil)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
[mapTable setValue: [object objectByDeserializing]
forKey: [key objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (id)objectForKey: (id)key
{
return [mapTable valueForKey: key];
}
- (size_t)count
{
return [mapTable count];
}
- (BOOL)isEqual: (id)dictionary
{
OFDictionary_hashtable *dictionary_;
if ([self class] != [OFDictionary_hashtable class] &&
[self class] != [OFMutableDictionary_hashtable class])
return [super isEqual: dictionary];
dictionary_ = (OFDictionary_hashtable*)dictionary;
return [dictionary_->mapTable isEqual: mapTable];
}
- (BOOL)containsObject: (id)object
{
return [mapTable containsValue: object];
}
- (BOOL)containsObjectIdenticalTo: (id)object
{
return [mapTable containsValueIdenticalTo: object];
}
- (OFArray*)allKeys
{
OFArray *ret;
id *keys;
size_t count;
count = [mapTable count];
keys = [self allocMemoryWithSize: sizeof(*keys)
count: count];
@try {
void *pool = objc_autoreleasePoolPush();
OFMapTableEnumerator *enumerator;
id key;
size_t i;
i = 0;
enumerator = [mapTable keyEnumerator];
while ((key = [enumerator nextValue]) != nil) {
assert(i < count);
keys[i++] = key;
}
objc_autoreleasePoolPop(pool);
|
|
|
|
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
|
objects = [element elementsForName: @"object"
namespace: OF_SERIALIZATION_NS];
if ([keys count] != [objects count])
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: [keys count]];
keyEnumerator = [keys objectEnumerator];
objectEnumerator = [objects objectEnumerator];
while ((keyElement = [keyEnumerator nextObject]) != nil &&
(objectElement = [objectEnumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
OFXMLElement *key, *object;
key = [[keyElement elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
object = [[objectElement elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
if (key == nil || object == nil)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
[_mapTable setValue: [object objectByDeserializing]
forKey: [key objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_mapTable dealloc];
[super dealloc];
}
- (id)objectForKey: (id)key
{
return [_mapTable valueForKey: key];
}
- (size_t)count
{
return [_mapTable count];
}
- (BOOL)isEqual: (id)dictionary
{
OFDictionary_hashtable *dictionary_;
if ([self class] != [OFDictionary_hashtable class] &&
[self class] != [OFMutableDictionary_hashtable class])
return [super isEqual: dictionary];
dictionary_ = (OFDictionary_hashtable*)dictionary;
return [dictionary_->_mapTable isEqual: _mapTable];
}
- (BOOL)containsObject: (id)object
{
return [_mapTable containsValue: object];
}
- (BOOL)containsObjectIdenticalTo: (id)object
{
return [_mapTable containsValueIdenticalTo: object];
}
- (OFArray*)allKeys
{
OFArray *ret;
id *keys;
size_t count;
count = [_mapTable count];
keys = [self allocMemoryWithSize: sizeof(*keys)
count: count];
@try {
void *pool = objc_autoreleasePoolPush();
OFMapTableEnumerator *enumerator;
id key;
size_t i;
i = 0;
enumerator = [_mapTable keyEnumerator];
while ((key = [enumerator nextValue]) != nil) {
assert(i < count);
keys[i++] = key;
}
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
- (OFArray*)allObjects
{
OFArray *ret;
id *objects;
size_t count;
count = [mapTable count];
objects = [self allocMemoryWithSize: sizeof(*objects)
count: count];
@try {
void *pool = objc_autoreleasePoolPush();
OFMapTableEnumerator *enumerator;
id object;
size_t i;
i = 0;
enumerator = [mapTable valueEnumerator];
while ((object = [enumerator nextValue]) != nil) {
assert(i < count);
objects[i++] = object;
}
objc_autoreleasePoolPop(pool);
ret = [OFArray arrayWithObjects: objects
count: count];
} @finally {
[self freeMemory: objects];
}
return ret;
}
- (OFEnumerator*)keyEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [mapTable keyEnumerator]
object: self] autorelease];
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [mapTable valueEnumerator]
object: self] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count_
{
return [mapTable countByEnumeratingWithState: state
objects: objects
count: count_];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndObjectsUsingBlock:
(of_dictionary_enumeration_block_t)block
{
@try {
[mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
- (void)dealloc
{
[mapTable dealloc];
[super dealloc];
}
- (uint32_t)hash
{
return [mapTable hash];
}
@end
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
|
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
- (OFArray*)allObjects
{
OFArray *ret;
id *objects;
size_t count;
count = [_mapTable count];
objects = [self allocMemoryWithSize: sizeof(*objects)
count: count];
@try {
void *pool = objc_autoreleasePoolPush();
OFMapTableEnumerator *enumerator;
id object;
size_t i;
i = 0;
enumerator = [_mapTable valueEnumerator];
while ((object = [enumerator nextValue]) != nil) {
assert(i < count);
objects[i++] = object;
}
objc_autoreleasePoolPop(pool);
ret = [OFArray arrayWithObjects: objects
count: count];
} @finally {
[self freeMemory: objects];
}
return ret;
}
- (OFEnumerator*)keyEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [_mapTable keyEnumerator]
object: self] autorelease];
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [_mapTable valueEnumerator]
object: self] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count
{
return [_mapTable countByEnumeratingWithState: state
objects: objects
count: count];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndObjectsUsingBlock:
(of_dictionary_enumeration_block_t)block
{
@try {
[_mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
- (uint32_t)hash
{
return [_mapTable hash];
}
@end
|
Modified src/OFFile.h
from [76b233d4a0]
to [5c8981b0ad].
︙ | | | ︙ | |
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#endif
/*!
* @brief A class which provides functions to read, write and manipulate files.
*/
@interface OFFile: OFSeekableStream
{
int fd;
BOOL closable;
BOOL atEndOfStream;
}
/*!
* @brief Creates a new OFFile with the specified path and mode.
*
* @param path The path to the file to open as a string
* @param mode The mode in which the file should be opened.@n
|
|
|
|
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
#endif
/*!
* @brief A class which provides functions to read, write and manipulate files.
*/
@interface OFFile: OFSeekableStream
{
int _fd;
BOOL _closable;
BOOL _atEndOfStream;
}
/*!
* @brief Creates a new OFFile with the specified path and mode.
*
* @param path The path to the file to open as a string
* @param mode The mode in which the file should be opened.@n
|
︙ | | | ︙ | |
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
*/
+ (instancetype)fileWithPath: (OFString*)path
mode: (OFString*)mode;
/*!
* @brief Creates a new OFFile with the specified file descriptor.
*
* @param fileDescriptor A file descriptor, returned from for example open().
* It is not closed when the OFFile object is deallocated!
* @return A new autoreleased OFFile
*/
+ (instancetype)fileWithFileDescriptor: (int)fileDescriptor;
/*!
* @brief Returns the path fo the current working directory.
*
* @return The path of the current working directory
*/
+ (OFString*)currentDirectoryPath;
|
|
|
|
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
*/
+ (instancetype)fileWithPath: (OFString*)path
mode: (OFString*)mode;
/*!
* @brief Creates a new OFFile with the specified file descriptor.
*
* @param fd A file descriptor, returned from for example open().
* It is not closed when the OFFile object is deallocated!
* @return A new autoreleased OFFile
*/
+ (instancetype)fileWithFileDescriptor: (int)fd;
/*!
* @brief Returns the path fo the current working directory.
*
* @return The path of the current working directory
*/
+ (OFString*)currentDirectoryPath;
|
︙ | | | ︙ | |
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
*/
- initWithPath: (OFString*)path
mode: (OFString*)mode;
/*!
* @brief Initializes an already allocated OFFile.
*
* @param fileDescriptor A file descriptor, returned from for example open().
* It is not closed when the OFFile object is deallocated!
*/
- initWithFileDescriptor: (int)fileDescriptor;
@end
#ifdef __cplusplus
extern "C" {
#endif
/*! @file */
|
|
|
|
|
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
*/
- initWithPath: (OFString*)path
mode: (OFString*)mode;
/*!
* @brief Initializes an already allocated OFFile.
*
* @param fd A file descriptor, returned from for example open().
* It is not closed when the OFFile object is deallocated!
*/
- initWithFileDescriptor: (int)fd;
@end
#ifdef __cplusplus
extern "C" {
#endif
/*! @file */
|
︙ | | | ︙ | |
Modified src/OFFile.m
from [a15c73b575]
to [7a0b90bbf0].
︙ | | | ︙ | |
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
length: length];
}
#if !defined(_WIN32) && !defined(_PSP)
if (!override) {
struct stat s;
if (fstat(sourceFile->fd, &s) == 0)
fchmod(destinationFile->fd, s.st_mode);
}
#else
(void)override;
#endif
} @finally {
[sourceFile close];
[destinationFile close];
|
|
|
|
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
length: length];
}
#if !defined(_WIN32) && !defined(_PSP)
if (!override) {
struct stat s;
if (fstat(sourceFile->_fd, &s) == 0)
fchmod(destinationFile->_fd, s.st_mode);
}
#else
(void)override;
#endif
} @finally {
[sourceFile close];
[destinationFile close];
|
︙ | | | ︙ | |
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
|
if ((flags = parse_mode([mode UTF8String])) == -1)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
#ifndef _WIN32
if ((fd = open([path cStringWithEncoding:
OF_STRING_ENCODING_NATIVE], flags, DEFAULT_MODE)) == -1)
#else
if ((fd = _wopen([path UTF16String], flags,
DEFAULT_MODE)) == -1)
#endif
@throw [OFOpenFileFailedException
exceptionWithClass: [self class]
path: path
mode: mode];
closable = YES;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithFileDescriptor: (int)fileDescriptor
{
self = [super init];
fd = fileDescriptor;
return self;
}
- (BOOL)lowlevelIsAtEndOfStream
{
if (fd == -1)
return YES;
return atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
ssize_t ret;
if (fd == -1 || atEndOfStream || (ret = read(fd, buffer, length)) < 0)
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
if (ret == 0)
atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
if (fd == -1 || atEndOfStream || write(fd, buffer, length) < length)
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
- (void)lowlevelSeekToOffset: (off_t)offset
whence: (int)whence
{
if (lseek(fd, offset, whence) == -1)
@throw [OFSeekFailedException exceptionWithClass: [self class]
stream: self
offset: offset
whence: whence];
}
- (int)fileDescriptorForReading
{
return fd;
}
- (int)fileDescriptorForWriting
{
return fd;
}
- (void)close
{
if (fd != -1)
close(fd);
fd = -1;
}
- (void)dealloc
{
if (closable && fd != -1)
close(fd);
[super dealloc];
}
@end
@implementation OFFileSingleton
+ (void)load
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
|
if ((flags = parse_mode([mode UTF8String])) == -1)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
#ifndef _WIN32
if ((_fd = open([path cStringWithEncoding:
OF_STRING_ENCODING_NATIVE], flags, DEFAULT_MODE)) == -1)
#else
if ((_fd = _wopen([path UTF16String], flags,
DEFAULT_MODE)) == -1)
#endif
@throw [OFOpenFileFailedException
exceptionWithClass: [self class]
path: path
mode: mode];
_closable = YES;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithFileDescriptor: (int)fd
{
self = [super init];
_fd = fd;
return self;
}
- (BOOL)lowlevelIsAtEndOfStream
{
if (_fd == -1)
return YES;
return _atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
ssize_t ret;
if (_fd == -1 || _atEndOfStream ||
(ret = read(_fd, buffer, length)) < 0)
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
if (ret == 0)
_atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
if (_fd == -1 || _atEndOfStream || write(_fd, buffer, length) < length)
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
- (void)lowlevelSeekToOffset: (off_t)offset
whence: (int)whence
{
if (lseek(_fd, offset, whence) == -1)
@throw [OFSeekFailedException exceptionWithClass: [self class]
stream: self
offset: offset
whence: whence];
}
- (int)fileDescriptorForReading
{
return _fd;
}
- (int)fileDescriptorForWriting
{
return _fd;
}
- (void)close
{
if (_fd != -1)
close(_fd);
_fd = -1;
}
- (void)dealloc
{
if (_closable && _fd != -1)
close(_fd);
[super dealloc];
}
@end
@implementation OFFileSingleton
+ (void)load
|
︙ | | | ︙ | |
Modified src/OFHTTPClient.h
from [19781d2abd]
to [97e24a8655].
︙ | | | ︙ | |
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
@end
/*!
* @brief A class for performing HTTP requests.
*/
@interface OFHTTPClient: OFObject
{
id <OFHTTPClientDelegate> delegate;
BOOL insecureRedirectsAllowed;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFHTTPClientDelegate> delegate;
@property BOOL insecureRedirectsAllowed;
#endif
|
|
|
|
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
@end
/*!
* @brief A class for performing HTTP requests.
*/
@interface OFHTTPClient: OFObject
{
id <OFHTTPClientDelegate> _delegate;
BOOL _insecureRedirectsAllowed;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFHTTPClientDelegate> delegate;
@property BOOL insecureRedirectsAllowed;
#endif
|
︙ | | | ︙ | |
Modified src/OFHTTPClient.m
from [8655f7b1b3]
to [bfff30b129].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
firstLetter = NO;
str++;
}
}
@interface OFHTTPClientReply: OFHTTPRequestReply
{
OFTCPSocket *sock;
BOOL chunked, atEndOfStream;
size_t toRead;
}
- initWithSocket: (OFTCPSocket*)sock;
@end
@implementation OFHTTPClientReply
- initWithSocket: (OFTCPSocket*)sock_
{
self = [super init];
sock = [sock_ retain];
return self;
}
- (void)dealloc
{
[sock release];
[super dealloc];
}
- (void)setHeaders: (OFDictionary*)headers_
{
[super setHeaders: headers_];
chunked = [[headers_ objectForKey: @"Transfer-Encoding"]
isEqual: @"chunked"];
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
if (!chunked)
return [sock readIntoBuffer: buffer
length: length];
if (toRead > 0) {
if (length > toRead)
length = toRead;
length = [sock readIntoBuffer: buffer
length: length];
toRead -= length;
if (toRead == 0)
if ([[sock readLine] length] > 0)
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
return length;
} else {
void *pool = objc_autoreleasePoolPush();
OFString *line;
of_range_t range;
@try {
line = [sock readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
range = [line rangeOfString: @";"];
if (range.location != OF_NOT_FOUND)
line = [line substringWithRange:
of_range(0, range.location)];
@try {
toRead =
(size_t)[line hexadecimalValue];
} @catch (OFInvalidFormatException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (toRead == 0) {
[sock close];
atEndOfStream = YES;
}
objc_autoreleasePoolPop(pool);
return 0;
}
}
- (BOOL)lowlevelIsAtEndOfStream
{
if (!chunked)
return [sock isAtEndOfStream];
return atEndOfStream;
}
- (int)fileDescriptorForReading
{
return [sock fileDescriptorForReading];
}
- (size_t)pendingBytes
{
return [super pendingBytes] + [sock pendingBytes];
}
- (void)close
{
[sock close];
}
@end
@implementation OFHTTPClient
+ (instancetype)client
{
return [[[self alloc] init] autorelease];
}
- (void)setDelegate: (id <OFHTTPClientDelegate>)delegate_
{
delegate = delegate_;
}
- (id <OFHTTPClientDelegate>)delegate
{
return delegate;
}
- (void)setInsecureRedirectsAllowed: (BOOL)allowed
{
insecureRedirectsAllowed = allowed;
}
- (BOOL)insecureRedirectsAllowed
{
return insecureRedirectsAllowed;
}
- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
{
return [self performRequest: request
redirects: 10];
}
- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
redirects: (size_t)redirects
{
void *pool = objc_autoreleasePoolPush();
OFURL *URL = [request URL];
OFString *scheme = [URL scheme];
of_http_request_type_t requestType = [request requestType];
OFDictionary *headers = [request headers];
OFDataArray *POSTData = [request POSTData];
OFTCPSocket *sock;
OFHTTPClientReply *reply;
OFString *line, *path, *version;
OFMutableDictionary *serverHeaders;
OFEnumerator *keyEnumerator, *objectEnumerator;
OFString *key, *object;
int status;
const char *type = NULL;
if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
@throw [OFUnsupportedProtocolException
exceptionWithClass: [self class]
URL: URL];
if ([scheme isEqual: @"http"])
sock = [OFTCPSocket socket];
else {
if (of_tls_socket_class == Nil)
@throw [OFUnsupportedProtocolException
exceptionWithClass: [self class]
URL: URL];
sock = [[[of_tls_socket_class alloc] init] autorelease];
}
if ([delegate respondsToSelector:
@selector(client:didCreateSocket:request:)])
[delegate client: self
didCreateSocket: sock
request: request];
[sock connectToHost: [URL host]
port: [URL port]];
/*
* Work around a bug with packet splitting in lighttpd when using
* HTTPS.
*/
[sock setWriteBufferEnabled: YES];
if (requestType == OF_HTTP_REQUEST_TYPE_GET)
type = "GET";
if (requestType == OF_HTTP_REQUEST_TYPE_HEAD)
type = "HEAD";
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
type = "POST";
if ([(path = [URL path]) length] == 0)
path = @"/";
if ([URL query] != nil)
[sock writeFormat: @"%s %@?%@ HTTP/%@\r\n",
type, path, [URL query], [request protocolVersionString]];
else
[sock writeFormat: @"%s %@ HTTP/%@\r\n",
type, path, [request protocolVersionString]];
if ([URL port] == 80)
[sock writeFormat: @"Host: %@\r\n", [URL host]];
else
[sock writeFormat: @"Host: %@:%d\r\n", [URL host],
[URL port]];
[sock writeString: @"Connection: close\r\n"];
if ([headers objectForKey: @"User-Agent"] == nil)
[sock writeString: @"User-Agent: Something using ObjFW "
@"<https://webkeks.org/objfw>\r\n"];
keyEnumerator = [headers keyEnumerator];
objectEnumerator = [headers objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[sock writeFormat: @"%@: %@\r\n", key, object];
if (requestType == OF_HTTP_REQUEST_TYPE_POST) {
OFString *contentType = [request MIMEType];
if (contentType == nil)
contentType = @"application/x-www-form-urlencoded; "
@"charset=UTF-8\r\n";
[sock writeFormat: @"Content-Type: %@\r\n", contentType];
[sock writeFormat: @"Content-Length: %d\r\n",
[POSTData count] * [POSTData itemSize]];
}
[sock writeString: @"\r\n"];
/* Work around a bug in lighttpd, see above */
[sock flushWriteBuffer];
[sock setWriteBufferEnabled: NO];
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
[sock writeBuffer: [POSTData items]
length: [POSTData count] * [POSTData itemSize]];
@try {
line = [sock readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (![line hasPrefix: @"HTTP/"] || [line characterAtIndex: 8] != ' ')
@throw [OFInvalidServerReplyException
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
|
firstLetter = NO;
str++;
}
}
@interface OFHTTPClientReply: OFHTTPRequestReply
{
OFTCPSocket *_socket;
BOOL _chunked, _atEndOfStream;
size_t _toRead;
}
- initWithSocket: (OFTCPSocket*)socket;
@end
@implementation OFHTTPClientReply
- initWithSocket: (OFTCPSocket*)socket
{
self = [super init];
_socket = [socket retain];
return self;
}
- (void)dealloc
{
[_socket release];
[super dealloc];
}
- (void)setHeaders: (OFDictionary*)headers
{
[super setHeaders: headers];
_chunked = [[headers objectForKey: @"Transfer-Encoding"]
isEqual: @"chunked"];
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
if (!_chunked)
return [_socket readIntoBuffer: buffer
length: length];
if (_toRead > 0) {
if (length > _toRead)
length = _toRead;
length = [_socket readIntoBuffer: buffer
length: length];
_toRead -= length;
if (_toRead == 0)
if ([[_socket readLine] length] > 0)
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
return length;
} else {
void *pool = objc_autoreleasePoolPush();
OFString *line;
of_range_t range;
@try {
line = [_socket readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
range = [line rangeOfString: @";"];
if (range.location != OF_NOT_FOUND)
line = [line substringWithRange:
of_range(0, range.location)];
@try {
_toRead =
(size_t)[line hexadecimalValue];
} @catch (OFInvalidFormatException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (_toRead == 0) {
[_socket close];
_atEndOfStream = YES;
}
objc_autoreleasePoolPop(pool);
return 0;
}
}
- (BOOL)lowlevelIsAtEndOfStream
{
if (!_chunked)
return [_socket isAtEndOfStream];
return _atEndOfStream;
}
- (int)fileDescriptorForReading
{
return [_socket fileDescriptorForReading];
}
- (size_t)pendingBytes
{
return [super pendingBytes] + [_socket pendingBytes];
}
- (void)close
{
[_socket close];
}
@end
@implementation OFHTTPClient
+ (instancetype)client
{
return [[[self alloc] init] autorelease];
}
- (void)setDelegate: (id <OFHTTPClientDelegate>)delegate
{
_delegate = delegate;
}
- (id <OFHTTPClientDelegate>)delegate
{
return _delegate;
}
- (void)setInsecureRedirectsAllowed: (BOOL)allowed
{
_insecureRedirectsAllowed = allowed;
}
- (BOOL)insecureRedirectsAllowed
{
return _insecureRedirectsAllowed;
}
- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
{
return [self performRequest: request
redirects: 10];
}
- (OFHTTPRequestReply*)performRequest: (OFHTTPRequest*)request
redirects: (size_t)redirects
{
void *pool = objc_autoreleasePoolPush();
OFURL *URL = [request URL];
OFString *scheme = [URL scheme];
of_http_request_type_t requestType = [request requestType];
OFDictionary *headers = [request headers];
OFDataArray *POSTData = [request POSTData];
OFTCPSocket *socket;
OFHTTPClientReply *reply;
OFString *line, *path, *version;
OFMutableDictionary *serverHeaders;
OFEnumerator *keyEnumerator, *objectEnumerator;
OFString *key, *object;
int status;
const char *type = NULL;
if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
@throw [OFUnsupportedProtocolException
exceptionWithClass: [self class]
URL: URL];
if ([scheme isEqual: @"http"])
socket = [OFTCPSocket socket];
else {
if (of_tls_socket_class == Nil)
@throw [OFUnsupportedProtocolException
exceptionWithClass: [self class]
URL: URL];
socket = [[[of_tls_socket_class alloc] init] autorelease];
}
if ([_delegate respondsToSelector:
@selector(client:didCreateSocket:request:)])
[_delegate client: self
didCreateSocket: socket
request: request];
[socket connectToHost: [URL host]
port: [URL port]];
/*
* Work around a bug with packet splitting in lighttpd when using
* HTTPS.
*/
[socket setWriteBufferEnabled: YES];
if (requestType == OF_HTTP_REQUEST_TYPE_GET)
type = "GET";
if (requestType == OF_HTTP_REQUEST_TYPE_HEAD)
type = "HEAD";
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
type = "POST";
if ([(path = [URL path]) length] == 0)
path = @"/";
if ([URL query] != nil)
[socket writeFormat: @"%s %@?%@ HTTP/%@\r\n",
type, path, [URL query], [request protocolVersionString]];
else
[socket writeFormat: @"%s %@ HTTP/%@\r\n",
type, path, [request protocolVersionString]];
if ([URL port] == 80)
[socket writeFormat: @"Host: %@\r\n", [URL host]];
else
[socket writeFormat: @"Host: %@:%d\r\n", [URL host],
[URL port]];
[socket writeString: @"Connection: close\r\n"];
if ([headers objectForKey: @"User-Agent"] == nil)
[socket writeString: @"User-Agent: Something using ObjFW "
@"<https://webkeks.org/objfw>\r\n"];
keyEnumerator = [headers keyEnumerator];
objectEnumerator = [headers objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[socket writeFormat: @"%@: %@\r\n", key, object];
if (requestType == OF_HTTP_REQUEST_TYPE_POST) {
OFString *contentType = [request MIMEType];
if (contentType == nil)
contentType = @"application/x-www-form-urlencoded; "
@"charset=UTF-8\r\n";
[socket writeFormat: @"Content-Type: %@\r\n", contentType];
[socket writeFormat: @"Content-Length: %d\r\n",
[POSTData count] * [POSTData itemSize]];
}
[socket writeString: @"\r\n"];
/* Work around a bug in lighttpd, see above */
[socket flushWriteBuffer];
[socket setWriteBufferEnabled: NO];
if (requestType == OF_HTTP_REQUEST_TYPE_POST)
[socket writeBuffer: [POSTData items]
length: [POSTData count] * [POSTData itemSize]];
@try {
line = [socket readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (![line hasPrefix: @"HTTP/"] || [line characterAtIndex: 8] != ' ')
@throw [OFInvalidServerReplyException
|
︙ | | | ︙ | |
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
|
for (;;) {
OFString *key, *value;
const char *lineC, *tmp;
char *keyC;
@try {
line = [sock readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (line == nil)
@throw [OFInvalidServerReplyException
|
|
|
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
|
for (;;) {
OFString *key, *value;
const char *lineC, *tmp;
char *keyC;
@try {
line = [socket readLine];
} @catch (OFInvalidEncodingException *e) {
@throw [OFInvalidServerReplyException
exceptionWithClass: [self class]];
}
if (line == nil)
@throw [OFInvalidServerReplyException
|
︙ | | | ︙ | |
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
|
tmp++;
} while (*tmp == ' ');
value = [OFString stringWithUTF8String: tmp];
if ((redirects > 0 && (status == 301 || status == 302 ||
status == 303 || status == 307) &&
[key isEqual: @"Location"]) && (insecureRedirectsAllowed ||
[scheme isEqual: @"http"] ||
![value hasPrefix: @"http://"])) {
OFURL *newURL;
OFHTTPRequest *newRequest;
BOOL follow = YES;
newURL = [OFURL URLWithString: value
relativeToURL: URL];
if ([delegate respondsToSelector:
@selector(client:shouldFollowRedirect:request:)])
follow = [delegate client: self
shouldFollowRedirect: newURL
request: request];
if (!follow) {
[serverHeaders setObject: value
forKey: key];
continue;
}
|
|
|
|
|
|
|
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
|
tmp++;
} while (*tmp == ' ');
value = [OFString stringWithUTF8String: tmp];
if ((redirects > 0 && (status == 301 || status == 302 ||
status == 303 || status == 307) &&
[key isEqual: @"Location"]) && (_insecureRedirectsAllowed ||
[scheme isEqual: @"http"] ||
![value hasPrefix: @"http://"])) {
OFURL *newURL;
OFHTTPRequest *newRequest;
BOOL follow = YES;
newURL = [OFURL URLWithString: value
relativeToURL: URL];
if ([_delegate respondsToSelector:
@selector(client:shouldFollowRedirect:request:)])
follow = [_delegate client: self
shouldFollowRedirect: newURL
request: request];
if (!follow) {
[serverHeaders setObject: value
forKey: key];
continue;
}
|
︙ | | | ︙ | |
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
|
[serverHeaders setObject: value
forKey: key];
}
[serverHeaders makeImmutable];
if ([delegate respondsToSelector:
@selector(client:didReceiveHeaders:statusCode:request:)])
[delegate client: self
didReceiveHeaders: serverHeaders
statusCode: status
request: request];
reply = [[OFHTTPClientReply alloc] initWithSocket: sock];
[reply setProtocolVersionFromString: version];
[reply setStatusCode: status];
[reply setHeaders: serverHeaders];
objc_autoreleasePoolPop(pool);
[reply autorelease];
|
|
|
|
|
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
|
[serverHeaders setObject: value
forKey: key];
}
[serverHeaders makeImmutable];
if ([_delegate respondsToSelector:
@selector(client:didReceiveHeaders:statusCode:request:)])
[_delegate client: self
didReceiveHeaders: serverHeaders
statusCode: status
request: request];
reply = [[OFHTTPClientReply alloc] initWithSocket: socket];
[reply setProtocolVersionFromString: version];
[reply setStatusCode: status];
[reply setHeaders: serverHeaders];
objc_autoreleasePoolPop(pool);
[reply autorelease];
|
︙ | | | ︙ | |
Modified src/OFHTTPRequest.h
from [eeab32f289]
to [f26f1fecd0].
︙ | | | ︙ | |
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
} of_http_request_protocol_version_t;
/*!
* @brief A class for storing HTTP requests.
*/
@interface OFHTTPRequest: OFObject
{
OFURL *URL;
of_http_request_type_t requestType;
of_http_request_protocol_version_t protocolVersion;
OFDictionary *headers;
OFDataArray *POSTData;
OFString *MIMEType;
OFString *remoteAddress;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFURL *URL;
@property of_http_request_type_t requestType;
@property of_http_request_protocol_version_t protocolVersion;
@property (copy) OFDictionary *headers;
|
|
|
|
|
|
|
|
|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
} of_http_request_protocol_version_t;
/*!
* @brief A class for storing HTTP requests.
*/
@interface OFHTTPRequest: OFObject
{
OFURL *_URL;
of_http_request_type_t _requestType;
of_http_request_protocol_version_t _protocolVersion;
OFDictionary *_headers;
OFDataArray *_POSTData;
OFString *_MIMEType;
OFString *_remoteAddress;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFURL *URL;
@property of_http_request_type_t requestType;
@property of_http_request_protocol_version_t protocolVersion;
@property (copy) OFDictionary *headers;
|
︙ | | | ︙ | |
Modified src/OFHTTPRequest.m
from [69b973a377]
to [67ed2116e0].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
return [[[self alloc] initWithURL: URL] autorelease];
}
- init
{
self = [super init];
requestType = OF_HTTP_REQUEST_TYPE_GET;
protocolVersion.major = 1;
protocolVersion.minor = 1;
return self;
}
- initWithURL: (OFURL*)URL_
{
self = [self init];
@try {
[self setURL: URL_];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[URL release];
[headers release];
[POSTData release];
[MIMEType release];
[remoteAddress release];
[super dealloc];
}
- (void)setURL: (OFURL*)URL_
{
OF_SETTER(URL, URL_, YES, 1)
}
- (OFURL*)URL
{
OF_GETTER(URL, YES)
}
- (void)setRequestType: (of_http_request_type_t)requestType_
{
requestType = requestType_;
}
- (of_http_request_type_t)requestType
{
return requestType;
}
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion_
{
if (protocolVersion_.major != 1 || protocolVersion.minor > 1)
@throw [OFUnsupportedVersionException
exceptionWithClass: [self class]
version: [OFString stringWithFormat: @"%u.%u",
protocolVersion_.major,
protocolVersion_.minor]];
protocolVersion = protocolVersion_;
}
- (of_http_request_protocol_version_t)protocolVersion
{
return protocolVersion;
}
- (void)setProtocolVersionFromString: (OFString*)string
{
void *pool = objc_autoreleasePoolPush();
OFArray *components = [string componentsSeparatedByString: @"."];
intmax_t major, minor;
of_http_request_protocol_version_t protocolVersion_;
if ([components count] != 2)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
major = [[components firstObject] decimalValue];
minor = [[components lastObject] decimalValue];
if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
protocolVersion_.major = (uint8_t)major;
protocolVersion_.minor = (uint8_t)minor;
[self setProtocolVersion: protocolVersion_];
objc_autoreleasePoolPop(pool);
}
- (OFString*)protocolVersionString
{
return [OFString stringWithFormat: @"%u.%u", protocolVersion.major,
protocolVersion.minor];
}
- (void)setHeaders: (OFDictionary*)headers_
{
OF_SETTER(headers, headers_, YES, 1)
}
- (OFDictionary*)headers
{
OF_GETTER(headers, YES)
}
- (void)setPOSTData: (OFDataArray*)POSTData_
{
OF_SETTER(POSTData, POSTData_, YES, 0)
}
- (OFDataArray*)POSTData
{
OF_GETTER(POSTData, YES)
}
- (void)setMIMEType: (OFString*)MIMEType_
{
OF_SETTER(MIMEType, MIMEType_, YES, 1)
}
- (OFString*)MIMEType
{
OF_GETTER(MIMEType, YES)
}
- (void)setRemoteAddress: (OFString*)remoteAddress_
{
OF_SETTER(remoteAddress, remoteAddress_, YES, 1)
}
- (OFString*)remoteAddress
{
OF_GETTER(remoteAddress, YES)
}
- (OFString*)description
{
void *pool = objc_autoreleasePoolPush();
const char *requestTypeStr = NULL;
OFString *indentedHeaders, *indentedPOSTData, *ret;
switch (requestType) {
case OF_HTTP_REQUEST_TYPE_GET:
requestTypeStr = "GET";
break;
case OF_HTTP_REQUEST_TYPE_POST:
requestTypeStr = "POST";
break;
case OF_HTTP_REQUEST_TYPE_HEAD:
requestTypeStr = "HEAD";
break;
}
indentedHeaders = [[headers description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
indentedPOSTData = [[POSTData description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
ret = [[OFString alloc] initWithFormat:
@"<%@:\n\tURL = %@\n"
@"\tRequest type = %s\n"
@"\tHeaders = %@\n"
@"\tPOST data = %@\n"
@"\tPOST data MIME type = %@\n"
@"\tRemote address = %@\n"
@">",
[self class], URL, requestTypeStr, indentedHeaders,
indentedPOSTData, MIMEType, remoteAddress];
objc_autoreleasePoolPop(pool);
return [ret autorelease];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
return [[[self alloc] initWithURL: URL] autorelease];
}
- init
{
self = [super init];
_requestType = OF_HTTP_REQUEST_TYPE_GET;
_protocolVersion.major = 1;
_protocolVersion.minor = 1;
return self;
}
- initWithURL: (OFURL*)URL
{
self = [self init];
@try {
[self setURL: URL];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_URL release];
[_headers release];
[_POSTData release];
[_MIMEType release];
[_remoteAddress release];
[super dealloc];
}
- (void)setURL: (OFURL*)URL
{
OF_SETTER(_URL, URL, YES, 1)
}
- (OFURL*)URL
{
OF_GETTER(_URL, YES)
}
- (void)setRequestType: (of_http_request_type_t)requestType
{
_requestType = requestType;
}
- (of_http_request_type_t)requestType
{
return _requestType;
}
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
if (protocolVersion.major != 1 || protocolVersion.minor > 1)
@throw [OFUnsupportedVersionException
exceptionWithClass: [self class]
version: [OFString stringWithFormat: @"%u.%u",
protocolVersion.major,
protocolVersion.minor]];
_protocolVersion = protocolVersion;
}
- (of_http_request_protocol_version_t)protocolVersion
{
return _protocolVersion;
}
- (void)setProtocolVersionFromString: (OFString*)string
{
void *pool = objc_autoreleasePoolPush();
OFArray *components = [string componentsSeparatedByString: @"."];
intmax_t major, minor;
of_http_request_protocol_version_t protocolVersion;
if ([components count] != 2)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
major = [[components firstObject] decimalValue];
minor = [[components lastObject] decimalValue];
if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
protocolVersion.major = (uint8_t)major;
protocolVersion.minor = (uint8_t)minor;
[self setProtocolVersion: protocolVersion];
objc_autoreleasePoolPop(pool);
}
- (OFString*)protocolVersionString
{
return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major,
_protocolVersion.minor];
}
- (void)setHeaders: (OFDictionary*)headers
{
OF_SETTER(_headers, headers, YES, 1)
}
- (OFDictionary*)headers
{
OF_GETTER(_headers, YES)
}
- (void)setPOSTData: (OFDataArray*)POSTData
{
OF_SETTER(_POSTData, POSTData, YES, 0)
}
- (OFDataArray*)POSTData
{
OF_GETTER(_POSTData, YES)
}
- (void)setMIMEType: (OFString*)MIMEType
{
OF_SETTER(_MIMEType, MIMEType, YES, 1)
}
- (OFString*)MIMEType
{
OF_GETTER(_MIMEType, YES)
}
- (void)setRemoteAddress: (OFString*)remoteAddress
{
OF_SETTER(_remoteAddress, remoteAddress, YES, 1)
}
- (OFString*)remoteAddress
{
OF_GETTER(_remoteAddress, YES)
}
- (OFString*)description
{
void *pool = objc_autoreleasePoolPush();
const char *requestTypeStr = NULL;
OFString *indentedHeaders, *indentedPOSTData, *ret;
switch (_requestType) {
case OF_HTTP_REQUEST_TYPE_GET:
requestTypeStr = "GET";
break;
case OF_HTTP_REQUEST_TYPE_POST:
requestTypeStr = "POST";
break;
case OF_HTTP_REQUEST_TYPE_HEAD:
requestTypeStr = "HEAD";
break;
}
indentedHeaders = [[_headers description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
indentedPOSTData = [[_POSTData description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
ret = [[OFString alloc] initWithFormat:
@"<%@:\n\tURL = %@\n"
@"\tRequest type = %s\n"
@"\tHeaders = %@\n"
@"\tPOST data = %@\n"
@"\tPOST data MIME type = %@\n"
@"\tRemote address = %@\n"
@">",
[self class], _URL, requestTypeStr, indentedHeaders,
indentedPOSTData, _MIMEType, _remoteAddress];
objc_autoreleasePoolPop(pool);
return [ret autorelease];
}
@end
|
Modified src/OFHTTPRequestReply.h
from [7576232cb8]
to [b047464ff4].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFDictionary;
/*!
* @brief A class for representing an HTTP request reply as a stream.
*/
@interface OFHTTPRequestReply: OFStream
{
of_http_request_protocol_version_t protocolVersion;
short statusCode;
OFDictionary *headers;
}
#ifdef OF_HAVE_PROPERTIES
@property of_http_request_protocol_version_t protocolVersion;
@property short statusCode;
@property (copy) OFDictionary *headers;
#endif
|
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFDictionary;
/*!
* @brief A class for representing an HTTP request reply as a stream.
*/
@interface OFHTTPRequestReply: OFStream
{
of_http_request_protocol_version_t _protocolVersion;
short _statusCode;
OFDictionary *_headers;
}
#ifdef OF_HAVE_PROPERTIES
@property of_http_request_protocol_version_t protocolVersion;
@property short statusCode;
@property (copy) OFDictionary *headers;
#endif
|
︙ | | | ︙ | |
Modified src/OFHTTPRequestReply.m
from [eadf4aca10]
to [bae34e8d9b].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#import "OFUnsupportedVersionException.h"
@implementation OFHTTPRequestReply
- init
{
self = [super init];
protocolVersion.major = 1;
protocolVersion.minor = 1;
return self;
}
- (void)dealloc
{
[headers release];
[super dealloc];
}
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion_
{
if (protocolVersion_.major != 1 || protocolVersion.minor > 1)
@throw [OFUnsupportedVersionException
exceptionWithClass: [self class]
version: [OFString stringWithFormat: @"%u.%u",
protocolVersion_.major,
protocolVersion_.minor]];
protocolVersion = protocolVersion_;
}
- (of_http_request_protocol_version_t)protocolVersion
{
return protocolVersion;
}
- (void)setProtocolVersionFromString: (OFString*)string
{
void *pool = objc_autoreleasePoolPush();
OFArray *components = [string componentsSeparatedByString: @"."];
intmax_t major, minor;
of_http_request_protocol_version_t protocolVersion_;
if ([components count] != 2)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
major = [[components firstObject] decimalValue];
minor = [[components lastObject] decimalValue];
if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
protocolVersion_.major = (uint8_t)major;
protocolVersion_.minor = (uint8_t)minor;
[self setProtocolVersion: protocolVersion_];
objc_autoreleasePoolPop(pool);
}
- (OFString*)protocolVersionString
{
return [OFString stringWithFormat: @"%u.%u", protocolVersion.major,
protocolVersion.minor];
}
- (short)statusCode
{
return statusCode;
}
- (void)setStatusCode: (short)statusCode_
{
statusCode = statusCode_;
}
- (OFDictionary*)headers
{
OF_GETTER(headers, YES)
}
- (void)setHeaders: (OFDictionary*)headers_
{
OF_SETTER(headers, headers_, YES, YES)
}
- (OFString*)description
{
void *pool = objc_autoreleasePoolPush();
OFString *indentedHeaders, *ret;
indentedHeaders = [[headers description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
ret = [[OFString alloc] initWithFormat:
@"<%@:\n"
@"\tStatus code = %d\n"
@"\tHeaders = %@\n"
@">",
[self class], statusCode, indentedHeaders];
objc_autoreleasePoolPop(pool);
return [ret autorelease];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#import "OFUnsupportedVersionException.h"
@implementation OFHTTPRequestReply
- init
{
self = [super init];
_protocolVersion.major = 1;
_protocolVersion.minor = 1;
return self;
}
- (void)dealloc
{
[_headers release];
[super dealloc];
}
- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
if (protocolVersion.major != 1 || protocolVersion.minor > 1)
@throw [OFUnsupportedVersionException
exceptionWithClass: [self class]
version: [OFString stringWithFormat: @"%u.%u",
protocolVersion.major,
protocolVersion.minor]];
_protocolVersion = protocolVersion;
}
- (of_http_request_protocol_version_t)protocolVersion
{
return _protocolVersion;
}
- (void)setProtocolVersionFromString: (OFString*)string
{
void *pool = objc_autoreleasePoolPush();
OFArray *components = [string componentsSeparatedByString: @"."];
intmax_t major, minor;
of_http_request_protocol_version_t protocolVersion;
if ([components count] != 2)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
major = [[components firstObject] decimalValue];
minor = [[components lastObject] decimalValue];
if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
protocolVersion.major = (uint8_t)major;
protocolVersion.minor = (uint8_t)minor;
[self setProtocolVersion: protocolVersion];
objc_autoreleasePoolPop(pool);
}
- (OFString*)protocolVersionString
{
return [OFString stringWithFormat: @"%u.%u", _protocolVersion.major,
_protocolVersion.minor];
}
- (short)statusCode
{
return _statusCode;
}
- (void)setStatusCode: (short)statusCode
{
_statusCode = statusCode;
}
- (OFDictionary*)headers
{
OF_GETTER(_headers, YES)
}
- (void)setHeaders: (OFDictionary*)headers
{
OF_SETTER(_headers, headers, YES, YES)
}
- (OFString*)description
{
void *pool = objc_autoreleasePoolPush();
OFString *indentedHeaders, *ret;
indentedHeaders = [[_headers description]
stringByReplacingOccurrencesOfString: @"\n"
withString: @"\n\t"];
ret = [[OFString alloc] initWithFormat:
@"<%@:\n"
@"\tStatus code = %d\n"
@"\tHeaders = %@\n"
@">",
[self class], _statusCode, indentedHeaders];
objc_autoreleasePoolPop(pool);
return [ret autorelease];
}
@end
|
Modified src/OFHTTPServer.h
from [3553c698ef]
to [bf775ba1f9].
︙ | | | ︙ | |
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
@end
/*!
* @brief A class for creating a simple HTTP server inside of applications.
*/
@interface OFHTTPServer: OFObject
{
OFString *host;
uint16_t port;
id <OFHTTPServerDelegate> delegate;
OFString *name;
OFTCPSocket *listeningSocket;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *host;
@property uint16_t port;
@property (assign) id <OFHTTPServerDelegate> delegate;
@property (copy) OFString *name;
|
|
|
|
|
|
|
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
@end
/*!
* @brief A class for creating a simple HTTP server inside of applications.
*/
@interface OFHTTPServer: OFObject
{
OFString *_host;
uint16_t _port;
id <OFHTTPServerDelegate> _delegate;
OFString *_name;
OFTCPSocket *_listeningSocket;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *host;
@property uint16_t port;
@property (assign) id <OFHTTPServerDelegate> delegate;
@property (copy) OFString *name;
|
︙ | | | ︙ | |
Modified src/OFHTTPServer.m
from [4524bb5e96]
to [7e47217e14].
︙ | | | ︙ | |
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
|
return [OFString stringWithUTF8StringNoCopy: cString
freeWhenDone: YES];
}
@interface OFHTTPServerReply: OFHTTPRequestReply
{
OFTCPSocket *sock;
OFHTTPServer *server;
BOOL chunked, headersSent, closed;
}
- initWithSocket: (OFTCPSocket*)sock
server: (OFHTTPServer*)server;
@end
@implementation OFHTTPServerReply
- initWithSocket: (OFTCPSocket*)sock_
server: (OFHTTPServer*)server_
{
self = [super init];
statusCode = 500;
sock = [sock_ retain];
server = [server_ retain];
return self;
}
- (void)dealloc
{
if (!closed)
[self close];
[sock release];
[server release];
[super dealloc];
}
- (void)sendHeaders
{
void *pool = objc_autoreleasePoolPush();
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
OFEnumerator *keyEnumerator, *valueEnumerator;
OFString *key, *value;
[sock writeFormat: @"HTTP/%@ %d %s\r\n"
@"Server: %@\r\n"
@"Date: %@\r\n",
[self protocolVersionString], statusCode,
status_code_to_string(statusCode),
[server name], date];
keyEnumerator = [headers keyEnumerator];
valueEnumerator = [headers objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(value = [valueEnumerator nextObject]) != nil)
if (![key isEqual: @"Server"] && ![key isEqual: @"Date"])
[sock writeFormat: @"%@: %@\r\n", key, value];
[sock writeString: @"\r\n"];
headersSent = YES;
chunked = [[headers objectForKey: @"Transfer-Encoding"]
isEqual: @"chunked"];
objc_autoreleasePoolPop(pool);
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
void *pool;
if (!headersSent)
[self sendHeaders];
if (!chunked) {
[sock writeBuffer: buffer
length: length];
return;
}
pool = objc_autoreleasePoolPush();
[sock writeString: [OFString stringWithFormat: @"%zx\r\n", length]];
objc_autoreleasePoolPop(pool);
[sock writeBuffer: buffer
length: length];
[sock writeBuffer: "\r\n"
length: 2];
}
- (void)close
{
if (!headersSent)
[self sendHeaders];
if (chunked)
[sock writeBuffer: "0\r\n\r\n"
length: 5];
[sock close];
closed = YES;
}
- (int)fileDescriptorForWriting
{
return [sock fileDescriptorForWriting];
}
@end
@interface OFHTTPServer_Connection: OFObject
{
OFTCPSocket *sock;
OFHTTPServer *server;
OFTimer *timer;
enum {
AWAITING_PROLOG,
PARSING_HEADERS,
SEND_REPLY
} state;
uint8_t HTTPMinorVersion;
of_http_request_type_t requestType;
OFString *host, *path;
uint16_t port;
OFMutableDictionary *headers;
size_t contentLength;
OFDataArray *POSTData;
}
- initWithSocket: (OFTCPSocket*)socket
server: (OFHTTPServer*)server;
- (BOOL)socket: (OFTCPSocket*)sock
didReadLine: (OFString*)line
exception: (OFException*)exception;
- (BOOL)parseProlog: (OFString*)line;
- (BOOL)parseHeaders: (OFString*)line;
- (BOOL)socket: (OFTCPSocket*)sock
didReadIntoBuffer: (const char*)buffer
length: (size_t)length
exception: (OFException*)exception;
- (BOOL)sendErrorAndClose: (short)statusCode;
- (void)createReply;
@end
@implementation OFHTTPServer_Connection
- initWithSocket: (OFTCPSocket*)sock_
server: (OFHTTPServer*)server_
{
self = [super init];
@try {
sock = [sock_ retain];
server = [server_ retain];
timer = [[OFTimer
scheduledTimerWithTimeInterval: 10
target: sock
selector: @selector(
cancelAsyncRequests)
repeats: NO] retain];
state = AWAITING_PROLOG;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sock release];
[server release];
[timer invalidate];
[timer release];
[host release];
[path release];
[headers release];
[POSTData release];
[super dealloc];
}
- (BOOL)socket: (OFTCPSocket*)sock_
didReadLine: (OFString*)line
exception: (OFException*)exception
{
if (line == nil || exception != nil)
return NO;
@try {
switch (state) {
case AWAITING_PROLOG:
return [self parseProlog: line];
case PARSING_HEADERS:
if (![self parseHeaders: line])
return NO;
if (state == SEND_REPLY) {
[self createReply];
return NO;
}
return YES;
default:
return NO;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
|
return [OFString stringWithUTF8StringNoCopy: cString
freeWhenDone: YES];
}
@interface OFHTTPServerReply: OFHTTPRequestReply
{
OFTCPSocket *_socket;
OFHTTPServer *_server;
BOOL _chunked, _headersSent, _closed;
}
- initWithSocket: (OFTCPSocket*)socket
server: (OFHTTPServer*)server;
@end
@implementation OFHTTPServerReply
- initWithSocket: (OFTCPSocket*)socket
server: (OFHTTPServer*)server
{
self = [super init];
_statusCode = 500;
_socket = [socket retain];
_server = [server retain];
return self;
}
- (void)dealloc
{
if (!_closed)
[self close];
[_socket release];
[_server release];
[super dealloc];
}
- (void)sendHeaders
{
void *pool = objc_autoreleasePoolPush();
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
OFEnumerator *keyEnumerator, *valueEnumerator;
OFString *key, *value;
[_socket writeFormat: @"HTTP/%@ %d %s\r\n"
@"Server: %@\r\n"
@"Date: %@\r\n",
[self protocolVersionString], _statusCode,
status_code_to_string(_statusCode),
[_server name], date];
keyEnumerator = [_headers keyEnumerator];
valueEnumerator = [_headers objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(value = [valueEnumerator nextObject]) != nil)
if (![key isEqual: @"Server"] && ![key isEqual: @"Date"])
[_socket writeFormat: @"%@: %@\r\n", key, value];
[_socket writeString: @"\r\n"];
_headersSent = YES;
_chunked = [[_headers objectForKey: @"Transfer-Encoding"]
isEqual: @"chunked"];
objc_autoreleasePoolPop(pool);
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
void *pool;
if (!_headersSent)
[self sendHeaders];
if (!_chunked) {
[_socket writeBuffer: buffer
length: length];
return;
}
pool = objc_autoreleasePoolPush();
[_socket writeString: [OFString stringWithFormat: @"%zx\r\n", length]];
objc_autoreleasePoolPop(pool);
[_socket writeBuffer: buffer
length: length];
[_socket writeBuffer: "\r\n"
length: 2];
}
- (void)close
{
if (!_headersSent)
[self sendHeaders];
if (_chunked)
[_socket writeBuffer: "0\r\n\r\n"
length: 5];
[_socket close];
_closed = YES;
}
- (int)fileDescriptorForWriting
{
return [_socket fileDescriptorForWriting];
}
@end
@interface OFHTTPServer_Connection: OFObject
{
OFTCPSocket *_socket;
OFHTTPServer *_server;
OFTimer *_timer;
enum {
AWAITING_PROLOG,
PARSING_HEADERS,
SEND_REPLY
} _state;
uint8_t _HTTPMinorVersion;
of_http_request_type_t _requestType;
OFString *_host, *_path;
uint16_t _port;
OFMutableDictionary *_headers;
size_t _contentLength;
OFDataArray *_POSTData;
}
- initWithSocket: (OFTCPSocket*)socket
server: (OFHTTPServer*)server;
- (BOOL)socket: (OFTCPSocket*)socket
didReadLine: (OFString*)line
exception: (OFException*)exception;
- (BOOL)parseProlog: (OFString*)line;
- (BOOL)parseHeaders: (OFString*)line;
- (BOOL)socket: (OFTCPSocket*)socket
didReadIntoBuffer: (const char*)buffer
length: (size_t)length
exception: (OFException*)exception;
- (BOOL)sendErrorAndClose: (short)statusCode;
- (void)createReply;
@end
@implementation OFHTTPServer_Connection
- initWithSocket: (OFTCPSocket*)socket
server: (OFHTTPServer*)server
{
self = [super init];
@try {
_socket = [socket retain];
_server = [server retain];
_timer = [[OFTimer
scheduledTimerWithTimeInterval: 10
target: socket
selector: @selector(
cancelAsyncRequests)
repeats: NO] retain];
_state = AWAITING_PROLOG;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_socket release];
[_server release];
[_timer invalidate];
[_timer release];
[_host release];
[_path release];
[_headers release];
[_POSTData release];
[super dealloc];
}
- (BOOL)socket: (OFTCPSocket*)socket
didReadLine: (OFString*)line
exception: (OFException*)exception
{
if (line == nil || exception != nil)
return NO;
@try {
switch (_state) {
case AWAITING_PROLOG:
return [self parseProlog: line];
case PARSING_HEADERS:
if (![self parseHeaders: line])
return NO;
if (_state == SEND_REPLY) {
[self createReply];
return NO;
}
return YES;
default:
return NO;
|
︙ | | | ︙ | |
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
|
if (![version hasPrefix: @" HTTP/1."])
return [self sendErrorAndClose: 505];
tmp = [version characterAtIndex: 8];
if (tmp < '0' || tmp > '9')
return [self sendErrorAndClose: 400];
HTTPMinorVersion = (uint8_t)(tmp - '0');
} @catch (OFOutOfRangeException *e) {
return [self sendErrorAndClose: 400];
}
pos = [line rangeOfString: @" "].location;
if (pos == OF_NOT_FOUND)
return [self sendErrorAndClose: 400];
type = [line substringWithRange: of_range(0, pos)];
if ([type isEqual: @"GET"])
requestType = OF_HTTP_REQUEST_TYPE_GET;
else if ([type isEqual: @"POST"])
requestType = OF_HTTP_REQUEST_TYPE_POST;
else if ([type isEqual: @"HEAD"])
requestType = OF_HTTP_REQUEST_TYPE_HEAD;
else
return [self sendErrorAndClose: 501];
@try {
path = [line substringWithRange:
of_range(pos + 1, [line length] - pos - 10)];
} @catch (OFOutOfRangeException *e) {
return [self sendErrorAndClose: 400];
}
path = [[path stringByDeletingEnclosingWhitespaces] retain];
if (![path hasPrefix: @"/"])
return [self sendErrorAndClose: 400];
headers = [[OFMutableDictionary alloc] init];
state = PARSING_HEADERS;
return YES;
}
- (BOOL)parseHeaders: (OFString*)line
{
OFString *key, *value;
size_t pos;
if ([line length] == 0) {
switch (requestType) {
case OF_HTTP_REQUEST_TYPE_GET:
case OF_HTTP_REQUEST_TYPE_HEAD:
state = SEND_REPLY;
break;
case OF_HTTP_REQUEST_TYPE_POST:;
OFString *tmp;
char *buffer;
tmp = [headers objectForKey: @"Content-Length"];
if (tmp == nil)
return [self sendErrorAndClose: 411];
@try {
contentLength = (size_t)[tmp decimalValue];
} @catch (OFInvalidFormatException *e) {
return [self sendErrorAndClose: 400];
}
buffer = [self allocMemoryWithSize: BUFFER_SIZE];
POSTData = [[OFDataArray alloc] init];
[sock asyncReadIntoBuffer: buffer
length: BUFFER_SIZE
target: self
selector: @selector(socket:
didReadIntoBuffer:
length:exception:)];
[timer setFireDate:
[OFDate dateWithTimeIntervalSinceNow: 5]];
return NO;
}
return YES;
}
pos = [line rangeOfString: @":"].location;
if (pos == OF_NOT_FOUND)
return [self sendErrorAndClose: 400];
key = [line substringWithRange: of_range(0, pos)];
value = [line substringWithRange:
of_range(pos + 1, [line length] - pos - 1)];
key = normalized_key([key stringByDeletingTrailingWhitespaces]);
value = [value stringByDeletingLeadingWhitespaces];
[headers setObject: value
forKey: key];
if ([key isEqual: @"Host"]) {
pos = [value
rangeOfString: @":"
options: OF_STRING_SEARCH_BACKWARDS].location;
if (pos != OF_NOT_FOUND) {
[host release];
host = [[value substringWithRange:
of_range(0, pos)] retain];
@try {
of_range_t range =
of_range(pos + 1, [value length] - pos - 1);
intmax_t portTmp = [[value
substringWithRange: range] decimalValue];
if (portTmp < 1 || portTmp > UINT16_MAX)
return [self sendErrorAndClose: 400];
port = (uint16_t)portTmp;
} @catch (OFInvalidFormatException *e) {
return [self sendErrorAndClose: 400];
}
} else {
[host release];
host = [value retain];
port = 80;
}
}
return YES;
}
- (BOOL)socket: (OFTCPSocket*)sock_
didReadIntoBuffer: (const char*)buffer
length: (size_t)length
exception: (OFException*)exception
{
if ([sock_ isAtEndOfStream] || exception != nil)
return NO;
[POSTData addItems: buffer
count: length];
if ([POSTData count] >= contentLength) {
@try {
[self createReply];
} @catch (OFWriteFailedException *e) {
return NO;
}
return NO;
}
[timer setFireDate: [OFDate dateWithTimeIntervalSinceNow: 5]];
return YES;
}
- (BOOL)sendErrorAndClose: (short)statusCode
{
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
[sock writeFormat: @"HTTP/1.1 %d %s\r\n"
@"Date: %@\r\n"
@"Server: %@\r\n"
@"\r\n",
statusCode, status_code_to_string(statusCode), date,
[server name]];
[sock close];
return NO;
}
- (void)createReply
{
OFURL *URL;
OFHTTPRequest *request;
OFHTTPServerReply *reply;
size_t pos;
[timer invalidate];
[timer release];
timer = nil;
if (host == nil || port == 0) {
if (HTTPMinorVersion > 0) {
[self sendErrorAndClose: 400];
return;
}
host = [[server host] retain];
port = [server port];
}
URL = [OFURL URL];
[URL setScheme: @"http"];
[URL setHost: host];
[URL setPort: port];
if ((pos = [path rangeOfString: @"?"].location) != OF_NOT_FOUND) {
OFString *path_, *query;
path_ = [path substringWithRange: of_range(0, pos)];
query = [path substringWithRange:
of_range(pos + 1, [path length] - pos - 1)];
[URL setPath: path_];
[URL setQuery: query];
} else
[URL setPath: path];
request = [OFHTTPRequest requestWithURL: URL];
[request setRequestType: requestType];
[request setProtocolVersion:
(of_http_request_protocol_version_t){ 1, HTTPMinorVersion }];
[request setHeaders: headers];
[request setPOSTData: POSTData];
[request setRemoteAddress: [sock remoteAddress]];
reply = [[[OFHTTPServerReply alloc]
initWithSocket: sock
server: server] autorelease];
[[server delegate] server: server
didReceiveRequest: request
reply: reply];
}
@end
@implementation OFHTTPServer
+ (instancetype)server
{
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
name = @"OFHTTPServer (ObjFW's HTTP server class "
@"<https://webkeks.org/objfw/>)";
return self;
}
- (void)dealloc
{
[host release];
[listeningSocket release];
[name release];
[super dealloc];
}
- (void)setHost: (OFString*)host_
{
OF_SETTER(host, host_, YES, 1)
}
- (OFString*)host
{
OF_GETTER(host, YES)
}
- (void)setPort: (uint16_t)port_
{
port = port_;
}
- (uint16_t)port
{
return port;
}
- (void)setDelegate: (id <OFHTTPServerDelegate>)delegate_
{
delegate = delegate_;
}
- (id <OFHTTPServerDelegate>)delegate
{
return delegate;
}
- (void)setName: (OFString*)name_
{
OF_SETTER(name, name_, YES, 1)
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (void)start
{
if (host == nil || port == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (listeningSocket != nil)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: listeningSocket];
listeningSocket = [[OFTCPSocket alloc] init];
[listeningSocket bindToHost: host
port: port];
[listeningSocket listen];
[listeningSocket asyncAcceptWithTarget: self
selector: @selector(OF_socket:
didAcceptSocket:
exception:)];
}
- (void)stop
{
[listeningSocket cancelAsyncRequests];
[listeningSocket release];
listeningSocket = nil;
}
- (BOOL)OF_socket: (OFTCPSocket*)socket
didAcceptSocket: (OFTCPSocket*)clientSocket
exception: (OFException*)exception
{
OFHTTPServer_Connection *connection;
if (exception != nil) {
if ([delegate respondsToSelector:
@selector(server:didReceiveExceptionOnListeningSocket:)])
return [delegate server: self
didReceiveExceptionOnListeningSocket: exception];
return NO;
}
connection = [[[OFHTTPServer_Connection alloc]
initWithSocket: clientSocket
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
|
if (![version hasPrefix: @" HTTP/1."])
return [self sendErrorAndClose: 505];
tmp = [version characterAtIndex: 8];
if (tmp < '0' || tmp > '9')
return [self sendErrorAndClose: 400];
_HTTPMinorVersion = (uint8_t)(tmp - '0');
} @catch (OFOutOfRangeException *e) {
return [self sendErrorAndClose: 400];
}
pos = [line rangeOfString: @" "].location;
if (pos == OF_NOT_FOUND)
return [self sendErrorAndClose: 400];
type = [line substringWithRange: of_range(0, pos)];
if ([type isEqual: @"GET"])
_requestType = OF_HTTP_REQUEST_TYPE_GET;
else if ([type isEqual: @"POST"])
_requestType = OF_HTTP_REQUEST_TYPE_POST;
else if ([type isEqual: @"HEAD"])
_requestType = OF_HTTP_REQUEST_TYPE_HEAD;
else
return [self sendErrorAndClose: 501];
@try {
_path = [line substringWithRange:
of_range(pos + 1, [line length] - pos - 10)];
} @catch (OFOutOfRangeException *e) {
return [self sendErrorAndClose: 400];
}
_path = [[_path stringByDeletingEnclosingWhitespaces] retain];
if (![_path hasPrefix: @"/"])
return [self sendErrorAndClose: 400];
_headers = [[OFMutableDictionary alloc] init];
_state = PARSING_HEADERS;
return YES;
}
- (BOOL)parseHeaders: (OFString*)line
{
OFString *key, *value;
size_t pos;
if ([line length] == 0) {
switch (_requestType) {
case OF_HTTP_REQUEST_TYPE_GET:
case OF_HTTP_REQUEST_TYPE_HEAD:
_state = SEND_REPLY;
break;
case OF_HTTP_REQUEST_TYPE_POST:;
OFString *tmp;
char *buffer;
tmp = [_headers objectForKey: @"Content-Length"];
if (tmp == nil)
return [self sendErrorAndClose: 411];
@try {
_contentLength = (size_t)[tmp decimalValue];
} @catch (OFInvalidFormatException *e) {
return [self sendErrorAndClose: 400];
}
buffer = [self allocMemoryWithSize: BUFFER_SIZE];
_POSTData = [[OFDataArray alloc] init];
[_socket asyncReadIntoBuffer: buffer
length: BUFFER_SIZE
target: self
selector: @selector(socket:
didReadIntoBuffer:
length:exception:)];
[_timer setFireDate:
[OFDate dateWithTimeIntervalSinceNow: 5]];
return NO;
}
return YES;
}
pos = [line rangeOfString: @":"].location;
if (pos == OF_NOT_FOUND)
return [self sendErrorAndClose: 400];
key = [line substringWithRange: of_range(0, pos)];
value = [line substringWithRange:
of_range(pos + 1, [line length] - pos - 1)];
key = normalized_key([key stringByDeletingTrailingWhitespaces]);
value = [value stringByDeletingLeadingWhitespaces];
[_headers setObject: value
forKey: key];
if ([key isEqual: @"Host"]) {
pos = [value
rangeOfString: @":"
options: OF_STRING_SEARCH_BACKWARDS].location;
if (pos != OF_NOT_FOUND) {
[_host release];
_host = [[value substringWithRange:
of_range(0, pos)] retain];
@try {
of_range_t range =
of_range(pos + 1, [value length] - pos - 1);
intmax_t portTmp = [[value
substringWithRange: range] decimalValue];
if (portTmp < 1 || portTmp > UINT16_MAX)
return [self sendErrorAndClose: 400];
_port = (uint16_t)portTmp;
} @catch (OFInvalidFormatException *e) {
return [self sendErrorAndClose: 400];
}
} else {
[_host release];
_host = [value retain];
_port = 80;
}
}
return YES;
}
- (BOOL)socket: (OFTCPSocket*)socket
didReadIntoBuffer: (const char*)buffer
length: (size_t)length
exception: (OFException*)exception
{
if ([socket isAtEndOfStream] || exception != nil)
return NO;
[_POSTData addItems: buffer
count: length];
if ([_POSTData count] >= _contentLength) {
@try {
[self createReply];
} @catch (OFWriteFailedException *e) {
return NO;
}
return NO;
}
[_timer setFireDate: [OFDate dateWithTimeIntervalSinceNow: 5]];
return YES;
}
- (BOOL)sendErrorAndClose: (short)statusCode
{
OFString *date = [[OFDate date]
dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];
[_socket writeFormat: @"HTTP/1.1 %d %s\r\n"
@"Date: %@\r\n"
@"Server: %@\r\n"
@"\r\n",
statusCode, status_code_to_string(statusCode),
date, [_server name]];
[_socket close];
return NO;
}
- (void)createReply
{
OFURL *URL;
OFHTTPRequest *request;
OFHTTPServerReply *reply;
size_t pos;
[_timer invalidate];
[_timer release];
_timer = nil;
if (_host == nil || _port == 0) {
if (_HTTPMinorVersion > 0) {
[self sendErrorAndClose: 400];
return;
}
[_host release];
_host = [[_server host] retain];
_port = [_server port];
}
URL = [OFURL URL];
[URL setScheme: @"http"];
[URL setHost: _host];
[URL setPort: _port];
if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) {
OFString *path, *query;
path = [_path substringWithRange: of_range(0, pos)];
query = [_path substringWithRange:
of_range(pos + 1, [path length] - pos - 1)];
[URL setPath: path];
[URL setQuery: query];
} else
[URL setPath: _path];
request = [OFHTTPRequest requestWithURL: URL];
[request setRequestType: _requestType];
[request setProtocolVersion:
(of_http_request_protocol_version_t){ 1, _HTTPMinorVersion }];
[request setHeaders: _headers];
[request setPOSTData: _POSTData];
[request setRemoteAddress: [_socket remoteAddress]];
reply = [[[OFHTTPServerReply alloc]
initWithSocket: _socket
server: _server] autorelease];
[[_server delegate] server: _server
didReceiveRequest: request
reply: reply];
}
@end
@implementation OFHTTPServer
+ (instancetype)server
{
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
_name = @"OFHTTPServer (ObjFW's HTTP server class "
@"<https://webkeks.org/objfw/>)";
return self;
}
- (void)dealloc
{
[_host release];
[_listeningSocket release];
[_name release];
[super dealloc];
}
- (void)setHost: (OFString*)host
{
OF_SETTER(_host, host, YES, 1)
}
- (OFString*)host
{
OF_GETTER(_host, YES)
}
- (void)setPort: (uint16_t)port
{
_port = port;
}
- (uint16_t)port
{
return _port;
}
- (void)setDelegate: (id <OFHTTPServerDelegate>)delegate
{
_delegate = delegate;
}
- (id <OFHTTPServerDelegate>)delegate
{
return _delegate;
}
- (void)setName: (OFString*)name
{
OF_SETTER(_name, name, YES, 1)
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (void)start
{
if (_host == nil || _port == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (_listeningSocket != nil)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: _listeningSocket];
_listeningSocket = [[OFTCPSocket alloc] init];
[_listeningSocket bindToHost: _host
port: _port];
[_listeningSocket listen];
[_listeningSocket asyncAcceptWithTarget: self
selector: @selector(OF_socket:
didAcceptSocket:
exception:)];
}
- (void)stop
{
[_listeningSocket cancelAsyncRequests];
[_listeningSocket release];
_listeningSocket = nil;
}
- (BOOL)OF_socket: (OFTCPSocket*)socket
didAcceptSocket: (OFTCPSocket*)clientSocket
exception: (OFException*)exception
{
OFHTTPServer_Connection *connection;
if (exception != nil) {
if ([_delegate respondsToSelector:
@selector(server:didReceiveExceptionOnListeningSocket:)])
return [_delegate server: self
didReceiveExceptionOnListeningSocket: exception];
return NO;
}
connection = [[[OFHTTPServer_Connection alloc]
initWithSocket: clientSocket
|
︙ | | | ︙ | |
Modified src/OFHash.h
from [f49dffade2]
to [9f5b79c75d].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFObject.h"
/*!
* @brief A base class for classes providing hash functions.
*/
@interface OFHash: OFObject
{
BOOL calculated;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isCalculated) BOOL calculated;
#endif
/*!
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFObject.h"
/*!
* @brief A base class for classes providing hash functions.
*/
@interface OFHash: OFObject
{
BOOL _calculated;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isCalculated) BOOL calculated;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/OFHash.m
from [20ad65b662]
to [f22a074494].
︙ | | | ︙ | |
49
50
51
52
53
54
55
56
57
58
|
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (BOOL)isCalculated
{
return calculated;
}
@end
|
|
|
49
50
51
52
53
54
55
56
57
58
|
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (BOOL)isCalculated
{
return _calculated;
}
@end
|
Modified src/OFIntrospection.h
from [8fcdbf99f7]
to [4b5b7170d8].
︙ | | | ︙ | |
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
@class OFMutableArray;
/*!
* @brief A class for describing a method.
*/
@interface OFMethod: OFObject
{
SEL selector;
OFString *name;
const char *typeEncoding;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
@property (readonly, copy) OFString *name;
@property (readonly) const char *typeEncoding;
#endif
|
|
|
|
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
@class OFMutableArray;
/*!
* @brief A class for describing a method.
*/
@interface OFMethod: OFObject
{
SEL _selector;
OFString *_name;
const char *_typeEncoding;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
@property (readonly, copy) OFString *name;
@property (readonly) const char *typeEncoding;
#endif
|
︙ | | | ︙ | |
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
@end
/*!
* @brief A class for describing an instance variable.
*/
@interface OFInstanceVariable: OFObject
{
OFString *name;
const char *typeEncoding;
ptrdiff_t offset;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name;
@property (readonly) ptrdiff_t offset;
@property (readonly) const char *typeEncoding;
#endif
|
|
|
|
|
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
@end
/*!
* @brief A class for describing an instance variable.
*/
@interface OFInstanceVariable: OFObject
{
OFString *_name;
const char *_typeEncoding;
ptrdiff_t _offset;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name;
@property (readonly) ptrdiff_t offset;
@property (readonly) const char *typeEncoding;
#endif
|
︙ | | | ︙ | |
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
@end
/*!
* @brief A class for introspecting classes.
*/
@interface OFIntrospection: OFObject
{
OFMutableArray *classMethods;
OFMutableArray *instanceMethods;
OFMutableArray *instanceVariables;
#ifdef OF_HAVE_PROPERTIES
OFMutableArray *properties;
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFArray *classMethods;
@property (readonly, copy) OFArray *instanceMethods;
@property (readonly, copy) OFArray *instanceVariables;
|
|
|
|
|
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
@end
/*!
* @brief A class for introspecting classes.
*/
@interface OFIntrospection: OFObject
{
OFMutableArray *_classMethods;
OFMutableArray *_instanceMethods;
OFMutableArray *_instanceVariables;
#ifdef OF_HAVE_PROPERTIES
OFMutableArray *_properties;
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFArray *classMethods;
@property (readonly, copy) OFArray *instanceMethods;
@property (readonly, copy) OFArray *instanceVariables;
|
︙ | | | ︙ | |
Modified src/OFIntrospection.m
from [59781cdf97]
to [562aeea48c].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
@implementation OFMethod
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithMethod: (struct objc_method*)method
{
self = [super init];
@try {
selector = (SEL)&method->sel;
name = [[OFString alloc]
initWithUTF8String: sel_getName(selector)];
typeEncoding = method->sel.types;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithMethod: (Method)method
{
self = [super init];
@try {
selector = method_getName(method);
name = [[OFString alloc]
initWithUTF8String: sel_getName(selector)];
typeEncoding = method_getTypeEncoding(method);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[name release];
[super dealloc];
}
- (SEL)selector
{
return selector;
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (const char*)typeEncoding
{
return typeEncoding;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<OFMethod: %@ [%s]>",
name, typeEncoding];
}
- (BOOL)isEqual: (id)object
{
OFMethod *otherMethod;
if (![object isKindOfClass: [OFMethod class]])
return NO;
otherMethod = object;
if (!sel_isEqual(otherMethod->selector, selector))
return NO;
if (![otherMethod->name isEqual: name])
return NO;
if ((otherMethod->typeEncoding == NULL && typeEncoding != NULL) ||
(otherMethod->typeEncoding != NULL && typeEncoding == NULL))
return NO;
if (otherMethod->typeEncoding != NULL && typeEncoding != NULL &&
strcmp(otherMethod->typeEncoding, typeEncoding))
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [name hash]);
if (typeEncoding != NULL) {
size_t i, length;
length = strlen(typeEncoding);
for (i = 0; i < length; i++)
OF_HASH_ADD(hash, typeEncoding[i]);
}
OF_HASH_FINALIZE(hash);
return hash;
}
@end
@implementation OFInstanceVariable
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithIvar: (struct objc_ivar*)ivar
{
self = [super init];
@try {
name = [[OFString alloc] initWithUTF8String: ivar->name];
typeEncoding = ivar->type;
offset = ivar->offset;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithIvar: (Ivar)ivar
{
self = [super init];
@try {
name = [[OFString alloc]
initWithUTF8String: ivar_getName(ivar)];
typeEncoding = ivar_getTypeEncoding(ivar);
offset = ivar_getOffset(ivar);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[name release];
[super dealloc];
}
- (OFString*)name
{
OF_GETTER(name, YES);
}
- (ptrdiff_t)offset
{
return offset;
}
- (const char*)typeEncoding
{
return typeEncoding;
}
- (OFString*)description
{
return [OFString stringWithFormat:
@"<OFInstanceVariable: %@ [%s] @ 0x%tx>",
name, typeEncoding, offset];
}
@end
@implementation OFIntrospection
+ (instancetype)introspectionWithClass: (Class)class
{
return [[[self alloc] initWithClass: class] autorelease];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
@implementation OFMethod
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithMethod: (struct objc_method*)method
{
self = [super init];
@try {
_selector = (SEL)&method->sel;
_name = [[OFString alloc]
initWithUTF8String: sel_getName(_selector)];
_typeEncoding = method->sel.types;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithMethod: (Method)method
{
self = [super init];
@try {
_selector = method_getName(method);
_name = [[OFString alloc]
initWithUTF8String: sel_getName(_selector)];
_typeEncoding = method_getTypeEncoding(method);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[_name release];
[super dealloc];
}
- (SEL)selector
{
return _selector;
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (const char*)typeEncoding
{
return _typeEncoding;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<OFMethod: %@ [%s]>",
_name, _typeEncoding];
}
- (BOOL)isEqual: (id)object
{
OFMethod *method;
if (![object isKindOfClass: [OFMethod class]])
return NO;
method = object;
if (!sel_isEqual(method->_selector, _selector))
return NO;
if (![method->_name isEqual: _name])
return NO;
if ((method->_typeEncoding == NULL && _typeEncoding != NULL) ||
(method->_typeEncoding != NULL && _typeEncoding == NULL))
return NO;
if (method->_typeEncoding != NULL && _typeEncoding != NULL &&
strcmp(method->_typeEncoding, _typeEncoding))
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_name hash]);
if (_typeEncoding != NULL) {
size_t i, length;
length = strlen(_typeEncoding);
for (i = 0; i < length; i++)
OF_HASH_ADD(hash, _typeEncoding[i]);
}
OF_HASH_FINALIZE(hash);
return hash;
}
@end
@implementation OFInstanceVariable
#if defined(OF_OBJFW_RUNTIME)
- OF_initWithIvar: (struct objc_ivar*)ivar
{
self = [super init];
@try {
_name = [[OFString alloc] initWithUTF8String: ivar->name];
_typeEncoding = ivar->type;
_offset = ivar->offset;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#elif defined(OF_APPLE_RUNTIME)
- OF_initWithIvar: (Ivar)ivar
{
self = [super init];
@try {
_name = [[OFString alloc]
initWithUTF8String: ivar_getName(ivar)];
_typeEncoding = ivar_getTypeEncoding(ivar);
_offset = ivar_getOffset(ivar);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[_name release];
[super dealloc];
}
- (OFString*)name
{
OF_GETTER(_name, YES);
}
- (ptrdiff_t)offset
{
return _offset;
}
- (const char*)typeEncoding
{
return _typeEncoding;
}
- (OFString*)description
{
return [OFString stringWithFormat:
@"<OFInstanceVariable: %@ [%s] @ 0x%tx>",
_name, _typeEncoding, _offset];
}
@end
@implementation OFIntrospection
+ (instancetype)introspectionWithClass: (Class)class
{
return [[[self alloc] initWithClass: class] autorelease];
|
︙ | | | ︙ | |
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
|
struct objc_method_list *methodList;
#elif defined(OF_APPLE_RUNTIME)
Method *methodList;
Ivar *ivarList;
unsigned i, count;
#endif
classMethods = [[OFMutableArray alloc] init];
instanceMethods = [[OFMutableArray alloc] init];
instanceVariables = [[OFMutableArray alloc] init];
#if defined(OF_OBJFW_RUNTIME)
for (methodList = object_getClass(class)->methodlist;
methodList != NULL; methodList = methodList->next) {
int i;
for (i = 0; i < methodList->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFMethod *method = [[OFMethod alloc]
OF_initWithMethod: &methodList->methods[i]];
[classMethods addObject: [method autorelease]];
objc_autoreleasePoolPop(pool);
}
}
for (methodList = class->methodlist; methodList != NULL;
methodList = methodList->next) {
int i;
for (i = 0; i < methodList->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFMethod *method = [[OFMethod alloc]
OF_initWithMethod: &methodList->methods[i]];
[instanceMethods addObject:
[method autorelease]];
objc_autoreleasePoolPop(pool);
}
}
if (class->ivars != NULL) {
unsigned i;
for (i = 0; i < class->ivars->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFInstanceVariable *ivar;
ivar = [[OFInstanceVariable alloc]
OF_initWithIvar: &class->ivars->ivars[i]];
[instanceVariables addObject:
[ivar autorelease]];
objc_autoreleasePoolPop(pool);
}
}
#elif defined(OF_APPLE_RUNTIME)
methodList = class_copyMethodList(object_getClass(class),
&count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[classMethods addObject: [[[OFMethod alloc]
OF_initWithMethod: methodList[i]]
autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(methodList);
}
methodList = class_copyMethodList(class, &count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[instanceMethods addObject: [[[OFMethod alloc]
OF_initWithMethod: methodList[i]]
autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(methodList);
}
ivarList = class_copyIvarList(class, &count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[instanceVariables addObject:
[[[OFInstanceVariable alloc]
OF_initWithIvar: ivarList[i]] autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(ivarList);
}
#endif
[classMethods makeImmutable];
[instanceMethods makeImmutable];
[instanceVariables makeImmutable];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[classMethods release];
[instanceMethods release];
[instanceVariables release];
[super dealloc];
}
- (OFArray*)classMethods
{
OF_GETTER(classMethods, YES)
}
- (OFArray*)instanceMethods
{
OF_GETTER(instanceMethods, YES)
}
- (OFArray*)instanceVariables
{
OF_GETTER(instanceVariables, YES)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
|
struct objc_method_list *methodList;
#elif defined(OF_APPLE_RUNTIME)
Method *methodList;
Ivar *ivarList;
unsigned i, count;
#endif
_classMethods = [[OFMutableArray alloc] init];
_instanceMethods = [[OFMutableArray alloc] init];
_instanceVariables = [[OFMutableArray alloc] init];
#if defined(OF_OBJFW_RUNTIME)
for (methodList = object_getClass(class)->methodlist;
methodList != NULL; methodList = methodList->next) {
int i;
for (i = 0; i < methodList->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFMethod *method = [[OFMethod alloc]
OF_initWithMethod: &methodList->methods[i]];
[_classMethods addObject: [method autorelease]];
objc_autoreleasePoolPop(pool);
}
}
for (methodList = class->methodlist; methodList != NULL;
methodList = methodList->next) {
int i;
for (i = 0; i < methodList->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFMethod *method = [[OFMethod alloc]
OF_initWithMethod: &methodList->methods[i]];
[_instanceMethods addObject:
[method autorelease]];
objc_autoreleasePoolPop(pool);
}
}
if (class->ivars != NULL) {
unsigned i;
for (i = 0; i < class->ivars->count; i++) {
void *pool = objc_autoreleasePoolPush();
OFInstanceVariable *ivar;
ivar = [[OFInstanceVariable alloc]
OF_initWithIvar: &class->ivars->ivars[i]];
[_instanceVariables addObject:
[ivar autorelease]];
objc_autoreleasePoolPop(pool);
}
}
#elif defined(OF_APPLE_RUNTIME)
methodList = class_copyMethodList(object_getClass(class),
&count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[_classMethods addObject: [[[OFMethod alloc]
OF_initWithMethod: methodList[i]]
autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(methodList);
}
methodList = class_copyMethodList(class, &count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[_instanceMethods addObject: [[[OFMethod alloc]
OF_initWithMethod: methodList[i]]
autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(methodList);
}
ivarList = class_copyIvarList(class, &count);
@try {
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[_instanceVariables addObject:
[[[OFInstanceVariable alloc]
OF_initWithIvar: ivarList[i]] autorelease]];
objc_autoreleasePoolPop(pool);
}
} @finally {
free(ivarList);
}
#endif
[_classMethods makeImmutable];
[_instanceMethods makeImmutable];
[_instanceVariables makeImmutable];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_classMethods release];
[_instanceMethods release];
[_instanceVariables release];
[super dealloc];
}
- (OFArray*)classMethods
{
OF_GETTER(_classMethods, YES)
}
- (OFArray*)instanceMethods
{
OF_GETTER(_instanceMethods, YES)
}
- (OFArray*)instanceVariables
{
OF_GETTER(_instanceVariables, YES)
}
@end
|
Modified src/OFList.h
from [f54b09d95a]
to [723cbad907].
︙ | | | ︙ | |
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
};
/*!
* @brief A class which provides easy to use double-linked lists.
*/
@interface OFList: OFObject <OFCopying, OFCollection, OFSerialization>
{
of_list_object_t *firstListObject;
of_list_object_t *lastListObject;
size_t count;
unsigned long mutations;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_list_object_t *firstListObject;
@property (readonly) of_list_object_t *lastListObject;
#endif
|
|
|
|
|
|
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
};
/*!
* @brief A class which provides easy to use double-linked lists.
*/
@interface OFList: OFObject <OFCopying, OFCollection, OFSerialization>
{
of_list_object_t *_firstListObject;
of_list_object_t *_lastListObject;
size_t _count;
unsigned long _mutations;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_list_object_t *firstListObject;
@property (readonly) of_list_object_t *lastListObject;
#endif
|
︙ | | | ︙ | |
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
* @brief Removes all objects from the list.
*/
- (void)removeAllObjects;
@end
@interface OFListEnumerator: OFEnumerator
{
OFList *list;
of_list_object_t *current;
unsigned long mutations;
unsigned long *mutationsPtr;
}
- initWithList: (OFList*)list
mutationsPointer: (unsigned long*)mutationsPtr;
@end
|
|
|
|
|
|
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
* @brief Removes all objects from the list.
*/
- (void)removeAllObjects;
@end
@interface OFListEnumerator: OFEnumerator
{
OFList *_list;
of_list_object_t *_current;
unsigned long _mutations;
unsigned long *_mutationsPtr;
}
- initWithList: (OFList*)list
mutationsPointer: (unsigned long*)mutationsPtr;
@end
|
Modified src/OFList.m
from [73617e55da]
to [c96b3b33fd].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
return self;
}
- (void)dealloc
{
of_list_object_t *iter;
for (iter = firstListObject; iter != NULL; iter = iter->next)
[iter->object release];
[super dealloc];
}
- (of_list_object_t*)firstListObject
{
return firstListObject;
}
- (of_list_object_t*)lastListObject
{
return lastListObject;
}
- (of_list_object_t*)appendObject: (id)object
{
of_list_object_t *listObject;
listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
listObject->object = [object retain];
listObject->next = NULL;
listObject->previous = lastListObject;
if (lastListObject != NULL)
lastListObject->next = listObject;
lastListObject = listObject;
if (firstListObject == NULL)
firstListObject = listObject;
count++;
mutations++;
return listObject;
}
- (of_list_object_t*)prependObject: (id)object
{
of_list_object_t *listObject;
listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
listObject->object = [object retain];
listObject->next = firstListObject;
listObject->previous = NULL;
if (firstListObject != NULL)
firstListObject->previous = listObject;
firstListObject = listObject;
if (lastListObject == NULL)
lastListObject = listObject;
count++;
mutations++;
return listObject;
}
- (of_list_object_t*)insertObject: (id)object
beforeListObject: (of_list_object_t*)listObject
{
of_list_object_t *newListObject;
newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
newListObject->object = [object retain];
newListObject->next = listObject;
newListObject->previous = listObject->previous;
if (listObject->previous != NULL)
listObject->previous->next = newListObject;
listObject->previous = newListObject;
if (listObject == firstListObject)
firstListObject = newListObject;
count++;
mutations++;
return newListObject;
}
- (of_list_object_t*)insertObject: (id)object
afterListObject: (of_list_object_t*)listObject
{
of_list_object_t *newListObject;
newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
newListObject->object = [object retain];
newListObject->next = listObject->next;
newListObject->previous = listObject;
if (listObject->next != NULL)
listObject->next->previous = newListObject;
listObject->next = newListObject;
if (listObject == lastListObject)
lastListObject = newListObject;
count++;
mutations++;
return newListObject;
}
- (void)removeListObject: (of_list_object_t*)listObject
{
if (listObject->previous != NULL)
listObject->previous->next = listObject->next;
if (listObject->next != NULL)
listObject->next->previous = listObject->previous;
if (firstListObject == listObject)
firstListObject = listObject->next;
if (lastListObject == listObject)
lastListObject = listObject->previous;
count--;
mutations++;
[listObject->object release];
[self freeMemory: listObject];
}
- (id)firstObject
{
return (firstListObject != NULL ? firstListObject->object : nil);
}
- (id)lastObject
{
return (lastListObject != NULL ? lastListObject->object : nil);
}
- (size_t)count
{
return count;
}
- (BOOL)isEqual: (id)object
{
OFList *otherList;
of_list_object_t *iter, *iter2;
if (![object isKindOfClass: [OFList class]])
return NO;
otherList = object;
if ([otherList count] != count)
return NO;
for (iter = firstListObject, iter2 = [otherList firstListObject];
iter != NULL && iter2 != NULL;
iter = iter->next, iter2 = iter2->next)
if (![iter->object isEqual: iter2->object])
return NO;
/* One is bigger than the other although we checked the count */
assert(iter == NULL && iter2 == NULL);
return YES;
}
- (BOOL)containsObject: (id)object
{
of_list_object_t *iter;
if (count == 0)
return NO;
for (iter = firstListObject; iter != NULL; iter = iter->next)
if ([iter->object isEqual: object])
return YES;
return NO;
}
- (BOOL)containsObjectIdenticalTo: (id)object
{
of_list_object_t *iter;
if (count == 0)
return NO;
for (iter = firstListObject; iter != NULL; iter = iter->next)
if (iter->object == object)
return YES;
return NO;
}
- (void)removeAllObjects
{
of_list_object_t *iter, *next;
mutations++;
for (iter = firstListObject; iter != NULL; iter = next) {
next = iter->next;
[iter->object release];
[self freeMemory: iter];
}
firstListObject = lastListObject = NULL;
}
- copy
{
OFList *copy = [[[self class] alloc] init];
of_list_object_t *iter, *listObject, *previous;
listObject = NULL;
previous = NULL;
@try {
for (iter = firstListObject; iter != NULL; iter = iter->next) {
listObject = [copy allocMemoryWithSize:
sizeof(of_list_object_t)];
listObject->object = [iter->object retain];
listObject->next = NULL;
listObject->previous = previous;
if (copy->firstListObject == NULL)
copy->firstListObject = listObject;
if (previous != NULL)
previous->next = listObject;
copy->count++;
previous = listObject;
}
} @catch (id e) {
[copy release];
@throw e;
}
copy->lastListObject = listObject;
return copy;
}
- (uint32_t)hash
{
of_list_object_t *iter;
uint32_t hash;
OF_HASH_INIT(hash);
for (iter = firstListObject; iter != NULL; iter = iter->next)
OF_HASH_ADD_HASH(hash, [iter->object hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFString*)description
{
OFMutableString *ret;
of_list_object_t *iter;
if (count == 0)
return @"[]";
ret = [OFMutableString stringWithString: @"[\n"];
for (iter = firstListObject; iter != NULL; iter = iter->next) {
void *pool = objc_autoreleasePoolPush();
[ret appendString: [iter->object description]];
if (iter->next != NULL)
[ret appendString: @",\n"];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
return self;
}
- (void)dealloc
{
of_list_object_t *iter;
for (iter = _firstListObject; iter != NULL; iter = iter->next)
[iter->object release];
[super dealloc];
}
- (of_list_object_t*)firstListObject
{
return _firstListObject;
}
- (of_list_object_t*)lastListObject
{
return _lastListObject;
}
- (of_list_object_t*)appendObject: (id)object
{
of_list_object_t *listObject;
listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
listObject->object = [object retain];
listObject->next = NULL;
listObject->previous = _lastListObject;
if (_lastListObject != NULL)
_lastListObject->next = listObject;
_lastListObject = listObject;
if (_firstListObject == NULL)
_firstListObject = listObject;
_count++;
_mutations++;
return listObject;
}
- (of_list_object_t*)prependObject: (id)object
{
of_list_object_t *listObject;
listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
listObject->object = [object retain];
listObject->next = _firstListObject;
listObject->previous = NULL;
if (_firstListObject != NULL)
_firstListObject->previous = listObject;
_firstListObject = listObject;
if (_lastListObject == NULL)
_lastListObject = listObject;
_count++;
_mutations++;
return listObject;
}
- (of_list_object_t*)insertObject: (id)object
beforeListObject: (of_list_object_t*)listObject
{
of_list_object_t *newListObject;
newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
newListObject->object = [object retain];
newListObject->next = listObject;
newListObject->previous = listObject->previous;
if (listObject->previous != NULL)
listObject->previous->next = newListObject;
listObject->previous = newListObject;
if (listObject == _firstListObject)
_firstListObject = newListObject;
_count++;
_mutations++;
return newListObject;
}
- (of_list_object_t*)insertObject: (id)object
afterListObject: (of_list_object_t*)listObject
{
of_list_object_t *newListObject;
newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
newListObject->object = [object retain];
newListObject->next = listObject->next;
newListObject->previous = listObject;
if (listObject->next != NULL)
listObject->next->previous = newListObject;
listObject->next = newListObject;
if (listObject == _lastListObject)
_lastListObject = newListObject;
_count++;
_mutations++;
return newListObject;
}
- (void)removeListObject: (of_list_object_t*)listObject
{
if (listObject->previous != NULL)
listObject->previous->next = listObject->next;
if (listObject->next != NULL)
listObject->next->previous = listObject->previous;
if (_firstListObject == listObject)
_firstListObject = listObject->next;
if (_lastListObject == listObject)
_lastListObject = listObject->previous;
_count--;
_mutations++;
[listObject->object release];
[self freeMemory: listObject];
}
- (id)firstObject
{
return (_firstListObject != NULL ? _firstListObject->object : nil);
}
- (id)lastObject
{
return (_lastListObject != NULL ? _lastListObject->object : nil);
}
- (size_t)count
{
return _count;
}
- (BOOL)isEqual: (id)object
{
OFList *list;
of_list_object_t *iter, *iter2;
if (![object isKindOfClass: [OFList class]])
return NO;
list = object;
if ([list count] != _count)
return NO;
for (iter = _firstListObject, iter2 = [list firstListObject];
iter != NULL && iter2 != NULL;
iter = iter->next, iter2 = iter2->next)
if (![iter->object isEqual: iter2->object])
return NO;
/* One is bigger than the other even though we checked the count */
assert(iter == NULL && iter2 == NULL);
return YES;
}
- (BOOL)containsObject: (id)object
{
of_list_object_t *iter;
if (_count == 0)
return NO;
for (iter = _firstListObject; iter != NULL; iter = iter->next)
if ([iter->object isEqual: object])
return YES;
return NO;
}
- (BOOL)containsObjectIdenticalTo: (id)object
{
of_list_object_t *iter;
if (_count == 0)
return NO;
for (iter = _firstListObject; iter != NULL; iter = iter->next)
if (iter->object == object)
return YES;
return NO;
}
- (void)removeAllObjects
{
of_list_object_t *iter, *next;
_mutations++;
for (iter = _firstListObject; iter != NULL; iter = next) {
next = iter->next;
[iter->object release];
[self freeMemory: iter];
}
_firstListObject = _lastListObject = NULL;
}
- copy
{
OFList *copy = [[[self class] alloc] init];
of_list_object_t *iter, *listObject, *previous;
listObject = NULL;
previous = NULL;
@try {
for (iter = _firstListObject; iter != NULL; iter = iter->next) {
listObject = [copy allocMemoryWithSize:
sizeof(of_list_object_t)];
listObject->object = [iter->object retain];
listObject->next = NULL;
listObject->previous = previous;
if (copy->_firstListObject == NULL)
copy->_firstListObject = listObject;
if (previous != NULL)
previous->next = listObject;
copy->_count++;
previous = listObject;
}
} @catch (id e) {
[copy release];
@throw e;
}
copy->_lastListObject = listObject;
return copy;
}
- (uint32_t)hash
{
of_list_object_t *iter;
uint32_t hash;
OF_HASH_INIT(hash);
for (iter = _firstListObject; iter != NULL; iter = iter->next)
OF_HASH_ADD_HASH(hash, [iter->object hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFString*)description
{
OFMutableString *ret;
of_list_object_t *iter;
if (_count == 0)
return @"[]";
ret = [OFMutableString stringWithString: @"[\n"];
for (iter = _firstListObject; iter != NULL; iter = iter->next) {
void *pool = objc_autoreleasePoolPush();
[ret appendString: [iter->object description]];
if (iter->next != NULL)
[ret appendString: @",\n"];
|
︙ | | | ︙ | |
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
{
OFXMLElement *element;
of_list_object_t *iter;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
for (iter = firstListObject; iter != NULL; iter = iter->next) {
void *pool = objc_autoreleasePoolPush();
[element addChild: [iter->object XMLElementBySerializing]];
objc_autoreleasePoolPop(pool);
}
return element;
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count_
{
of_list_object_t **listObject = (of_list_object_t**)&state->extra[0];
int i;
state->itemsPtr = objects;
state->mutationsPtr = &mutations;
if (state->state == 0) {
*listObject = firstListObject;
state->state = 1;
}
for (i = 0; i < count_; i++) {
if (*listObject == NULL)
return i;
objects[i] = (*listObject)->object;
*listObject = (*listObject)->next;
}
return count_;
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFListEnumerator alloc]
initWithList: self
mutationsPointer: &mutations] autorelease];
}
@end
@implementation OFListEnumerator
- initWithList: (OFList*)list_
mutationsPointer: (unsigned long*)mutationsPtr_
{
self = [super init];
list = [list_ retain];
current = [list firstListObject];
mutations = *mutationsPtr_;
mutationsPtr = mutationsPtr_;
return self;
}
- (void)dealloc
{
[list release];
[super dealloc];
}
- (id)nextObject
{
id ret;
if (*mutationsPtr != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: list];
if (current == NULL)
return nil;
ret = current->object;
current = current->next;
return ret;
}
- (void)reset
{
if (*mutationsPtr != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: list];
current = [list firstListObject];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
{
OFXMLElement *element;
of_list_object_t *iter;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
for (iter = _firstListObject; iter != NULL; iter = iter->next) {
void *pool = objc_autoreleasePoolPush();
[element addChild: [iter->object XMLElementBySerializing]];
objc_autoreleasePoolPop(pool);
}
return element;
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count
{
of_list_object_t **listObject = (of_list_object_t**)&state->extra[0];
int i;
state->itemsPtr = objects;
state->mutationsPtr = &_mutations;
if (state->state == 0) {
*listObject = _firstListObject;
state->state = 1;
}
for (i = 0; i < count; i++) {
if (*listObject == NULL)
return i;
objects[i] = (*listObject)->object;
*listObject = (*listObject)->next;
}
return count;
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFListEnumerator alloc]
initWithList: self
mutationsPointer: &_mutations] autorelease];
}
@end
@implementation OFListEnumerator
- initWithList: (OFList*)list
mutationsPointer: (unsigned long*)mutationsPtr
{
self = [super init];
_list = [list retain];
_current = [list firstListObject];
_mutations = *mutationsPtr;
_mutationsPtr = mutationsPtr;
return self;
}
- (void)dealloc
{
[_list release];
[super dealloc];
}
- (id)nextObject
{
id ret;
if (*_mutationsPtr != _mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: _list];
if (_current == NULL)
return nil;
ret = _current->object;
_current = _current->next;
return ret;
}
- (void)reset
{
if (*_mutationsPtr != _mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: _list];
_current = [_list firstListObject];
}
@end
|
Modified src/OFMD5Hash.h
from [8c63eab3b8]
to [efbff1e954].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#define OF_MD5_DIGEST_SIZE 16
/*!
* @brief A class which provides functions to create an MD5 hash.
*/
@interface OFMD5Hash: OFHash
{
uint32_t buffer[4];
uint32_t bits[2];
union {
uint8_t u8[64];
uint32_t u32[16];
} in;
}
@end
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#define OF_MD5_DIGEST_SIZE 16
/*!
* @brief A class which provides functions to create an MD5 hash.
*/
@interface OFMD5Hash: OFHash
{
uint32_t _buffer[4];
uint32_t _bits[2];
union {
uint8_t u8[64];
uint32_t u32[16];
} _in;
}
@end
|
Modified src/OFMD5Hash.m
from [b7d6fe40cf]
to [f6e92bc9b9].
︙ | | | ︙ | |
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
return 64;
}
- init
{
self = [super init];
buffer[0] = 0x67452301;
buffer[1] = 0xEFCDAB89;
buffer[2] = 0x98BADCFE;
buffer[3] = 0x10325476;
return self;
}
- (void)updateWithBuffer: (const void*)buffer__
length: (size_t)length
{
uint32_t t;
const char *buffer_ = buffer__;
if (length == 0)
return;
if (calculated)
@throw [OFHashAlreadyCalculatedException
exceptionWithClass: [self class]
hash: self];
/* Update bitcount */
t = bits[0];
if ((bits[0] = t + ((uint32_t)length << 3)) < t)
/* Carry from low to high */
bits[1]++;
bits[1] += (uint32_t)length >> 29;
/* Bytes already in shsInfo->data */
t = (t >> 3) & 0x3F;
/* Handle any leading odd-sized chunks */
if (t) {
uint8_t *p = in.u8 + t;
t = 64 - t;
if (length < t) {
memcpy(p, buffer_, length);
return;
}
memcpy(p, buffer_, t);
BSWAP32_VEC_IF_BE(in.u32, 16);
md5_transform(buffer, in.u32);
buffer_ += t;
length -= t;
}
/* Process data in 64-byte chunks */
while (length >= 64) {
memcpy(in.u8, buffer_, 64);
BSWAP32_VEC_IF_BE(in.u32, 16);
md5_transform(buffer, in.u32);
buffer_ += 64;
length -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(in.u8, buffer_, length);
}
- (uint8_t*)digest
{
uint8_t *p;
size_t count;
if (calculated)
return (uint8_t*)buffer;
/* Compute number of bytes mod 64 */
count = (bits[0] >> 3) & 0x3F;
/*
* Set the first char of padding to 0x80. This is safe since there is
* always at least one byte free
*/
p = in.u8 + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
BSWAP32_VEC_IF_BE(in.u32, 16);
md5_transform(buffer, in.u32);
/* Now fill the next block with 56 bytes */
memset(in.u8, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
BSWAP32_VEC_IF_BE(in.u32, 14);
/* Append length in bits and transform */
in.u32[14] = bits[0];
in.u32[15] = bits[1];
md5_transform(buffer, in.u32);
BSWAP32_VEC_IF_BE(buffer, 4);
calculated = YES;
return (uint8_t*)buffer;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
return 64;
}
- init
{
self = [super init];
_buffer[0] = 0x67452301;
_buffer[1] = 0xEFCDAB89;
_buffer[2] = 0x98BADCFE;
_buffer[3] = 0x10325476;
return self;
}
- (void)updateWithBuffer: (const void*)buffer_
length: (size_t)length
{
uint32_t t;
const char *buffer = buffer_;
if (length == 0)
return;
if (_calculated)
@throw [OFHashAlreadyCalculatedException
exceptionWithClass: [self class]
hash: self];
/* Update bitcount */
t = _bits[0];
if ((_bits[0] = t + ((uint32_t)length << 3)) < t)
/* Carry from low to high */
_bits[1]++;
_bits[1] += (uint32_t)length >> 29;
/* Bytes already in shsInfo->data */
t = (t >> 3) & 0x3F;
/* Handle any leading odd-sized chunks */
if (t) {
uint8_t *p = _in.u8 + t;
t = 64 - t;
if (length < t) {
memcpy(p, buffer, length);
return;
}
memcpy(p, buffer, t);
BSWAP32_VEC_IF_BE(in.u32, 16);
md5_transform(_buffer, _in.u32);
buffer += t;
length -= t;
}
/* Process data in 64-byte chunks */
while (length >= 64) {
memcpy(_in.u8, buffer, 64);
BSWAP32_VEC_IF_BE(_in.u32, 16);
md5_transform(_buffer, _in.u32);
buffer += 64;
length -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(_in.u8, buffer, length);
}
- (uint8_t*)digest
{
uint8_t *p;
size_t count;
if (_calculated)
return (uint8_t*)_buffer;
/* Compute number of bytes mod 64 */
count = (_bits[0] >> 3) & 0x3F;
/*
* Set the first char of padding to 0x80. This is safe since there is
* always at least one byte free
*/
p = _in.u8 + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
BSWAP32_VEC_IF_BE(_in.u32, 16);
md5_transform(_buffer, _in.u32);
/* Now fill the next block with 56 bytes */
memset(_in.u8, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
BSWAP32_VEC_IF_BE(in.u32, 14);
/* Append length in bits and transform */
_in.u32[14] = _bits[0];
_in.u32[15] = _bits[1];
md5_transform(_buffer, _in.u32);
BSWAP32_VEC_IF_BE(_buffer, 4);
_calculated = YES;
return (uint8_t*)_buffer;
}
@end
|
Modified src/OFMapTable.h
from [7677133529]
to [c74d98dfe6].
︙ | | | ︙ | |
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
/**
* @brief A class similar to OFDictionary, but providing more options how keys
* and values should be retained, released, compared and hashed.
*/
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
of_map_table_functions_t keyFunctions, valueFunctions;
struct of_map_table_bucket **buckets;
uint32_t minCapacity, capacity, count;
uint8_t rotate;
unsigned long mutations;
}
/*!
* @brief Creates a new OFMapTable with the specified key and value functions.
*
* @param keyFunctions A structure of functions for handling keys
* @param valueFunctions A structure of functions for handling values
|
|
|
|
|
|
|
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
/**
* @brief A class similar to OFDictionary, but providing more options how keys
* and values should be retained, released, compared and hashed.
*/
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
of_map_table_functions_t _keyFunctions, _valueFunctions;
struct of_map_table_bucket **_buckets;
uint32_t _minCapacity, _capacity, _count;
uint8_t _rotate;
unsigned long _mutations;
}
/*!
* @brief Creates a new OFMapTable with the specified key and value functions.
*
* @param keyFunctions A structure of functions for handling keys
* @param valueFunctions A structure of functions for handling values
|
︙ | | | ︙ | |
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
/*!
* @brief A class which provides methods to enumerate through an OFMapTable's
* keys or values.
*/
@interface OFMapTableEnumerator: OFObject
{
OFMapTable *mapTable;
struct of_map_table_bucket **buckets;
uint32_t capacity;
unsigned long mutations;
unsigned long *mutationsPtr;
uint32_t position;
}
- OF_initWithMapTable: (OFMapTable*)mapTable_
buckets: (struct of_map_table_bucket**)buckets_
capacity: (uint32_t)capacity_
mutationsPointer: (unsigned long*)mutationsPtr_;
/*!
* @brief Returns the next value.
*
* @return The next value
*/
- (void*)nextValue;
/*!
* @brief Resets the enumerator, so the next call to nextKey returns the first
* key again.
*/
- (void)reset;
@end
@interface OFMapTableEnumeratorWrapper: OFEnumerator
{
OFMapTableEnumerator *enumerator;
id object;
}
- initWithEnumerator: (OFMapTableEnumerator*)enumerator
object: (id)object;
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
/*!
* @brief A class which provides methods to enumerate through an OFMapTable's
* keys or values.
*/
@interface OFMapTableEnumerator: OFObject
{
OFMapTable *_mapTable;
struct of_map_table_bucket **_buckets;
uint32_t _capacity;
unsigned long _mutations;
unsigned long *_mutationsPtr;
uint32_t _position;
}
- OF_initWithMapTable: (OFMapTable*)mapTable
buckets: (struct of_map_table_bucket**)buckets
capacity: (uint32_t)capacity
mutationsPointer: (unsigned long*)mutationsPtr;
/*!
* @brief Returns the next value.
*
* @return The next value
*/
- (void*)nextValue;
/*!
* @brief Resets the enumerator, so the next call to nextKey returns the first
* key again.
*/
- (void)reset;
@end
@interface OFMapTableEnumeratorWrapper: OFEnumerator
{
OFMapTableEnumerator *_enumerator;
id _object;
}
- initWithEnumerator: (OFMapTableEnumerator*)enumerator
object: (id)object;
@end
|
Modified src/OFMapTable.m
from [01662f5402]
to [212223cd50].
︙ | | | ︙ | |
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
|
[self release];
@throw e;
}
abort();
}
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions_
valueFunctions: (of_map_table_functions_t)valueFunctions_
{
return [self initWithKeyFunctions: keyFunctions_
valueFunctions: valueFunctions_
capacity: 0];
}
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions_
valueFunctions: (of_map_table_functions_t)valueFunctions_
capacity: (size_t)capacity_
{
self = [super init];
@try {
keyFunctions = keyFunctions_;
valueFunctions = valueFunctions_;
#define SET_DEFAULT(var, value) \
if (var == NULL) \
var = value;
SET_DEFAULT(keyFunctions.retain, default_retain);
SET_DEFAULT(keyFunctions.release, default_release);
SET_DEFAULT(keyFunctions.hash, default_hash);
SET_DEFAULT(keyFunctions.equal, default_equal);
SET_DEFAULT(valueFunctions.retain, default_retain);
SET_DEFAULT(valueFunctions.release, default_release);
SET_DEFAULT(valueFunctions.hash, default_hash);
SET_DEFAULT(valueFunctions.equal, default_equal);
#undef SET_DEFAULT
if (capacity_ > UINT32_MAX ||
capacity_ > UINT32_MAX / sizeof(*buckets) ||
capacity_ > UINT32_MAX / 8)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
for (capacity = 1; capacity < capacity_; capacity <<= 1);
if (capacity_ * 8 / capacity >= 6)
capacity <<= 1;
if (capacity < MIN_CAPACITY)
capacity = MIN_CAPACITY;
minCapacity = capacity;
buckets = [self allocMemoryWithSize: sizeof(*buckets)
count: capacity];
memset(buckets, 0, capacity * sizeof(*buckets));
if (of_hash_seed != 0)
#if defined(HAVE_ARC4RANDOM)
rotate = arc4random() & 31;
#elif defined(HAVE_RANDOM)
rotate = random() & 31;
#else
rotate = rand() & 31;
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
uint32_t i;
for (i = 0; i < capacity; i++) {
if (buckets[i] != NULL && buckets[i] != &deleted) {
keyFunctions.release(buckets[i]->key);
valueFunctions.release(buckets[i]->value);
}
}
[super dealloc];
}
- (BOOL)isEqual: (id)mapTable_
{
OFMapTable *mapTable;
uint32_t i;
if (![mapTable_ isKindOfClass: [OFMapTable class]])
return NO;
mapTable = mapTable_;
if (mapTable->count != count ||
mapTable->keyFunctions.equal != keyFunctions.equal ||
mapTable->valueFunctions.equal != valueFunctions.equal)
return NO;
for (i = 0; i < capacity; i++) {
if (buckets[i] != NULL && buckets[i] != &deleted) {
void *value = [mapTable valueForKey: buckets[i]->key];
if (!valueFunctions.equal(value, buckets[i]->value))
return NO;
}
}
return YES;
}
- (uint32_t)hash
{
uint32_t i, hash = 0;
for (i = 0; i < capacity; i++) {
if (buckets[i] != NULL && buckets[i] != &deleted) {
hash += OF_ROR(buckets[i]->hash, rotate);
hash += valueFunctions.hash(buckets[i]->value);
}
}
return hash;
}
- (id)copy
{
OFMapTable *copy = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: capacity];
@try {
uint32_t i;
for (i = 0; i < capacity; i++)
if (buckets[i] != NULL && buckets[i] != &deleted)
[copy OF_setValue: buckets[i]->value
forKey: buckets[i]->key
hash: OF_ROR(buckets[i]->hash,
rotate)];
} @catch (id e) {
[copy release];
@throw e;
}
copy->minCapacity = MIN_CAPACITY;
return copy;
}
- (size_t)count
{
return count;
}
- (void*)valueForKey: (void*)key
{
uint32_t i, hash, last;
if (key == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(keyFunctions.hash(key), rotate);
last = capacity;
for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key))
return buckets[i]->value;
}
if (i < last)
return nil;
/* In case the last bucket is already used */
last = hash & (capacity - 1);
for (i = 0; i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key))
return buckets[i]->value;
}
return NULL;
}
- (void)OF_resizeForCount: (uint32_t)newCount
{
uint32_t i, fullness, newCapacity;
struct of_map_table_bucket **newBuckets;
if (newCount > UINT32_MAX || newCount > UINT32_MAX / sizeof(*buckets) ||
newCount > UINT32_MAX / 8)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
fullness = newCount * 8 / capacity;
if (fullness >= 6)
newCapacity = capacity << 1;
else if (fullness <= 1)
newCapacity = capacity >> 1;
else
return;
if (newCapacity < capacity && newCapacity < minCapacity)
return;
newBuckets = [self allocMemoryWithSize: sizeof(*newBuckets)
count: newCapacity];
for (i = 0; i < newCapacity; i++)
newBuckets[i] = NULL;
for (i = 0; i < capacity; i++) {
if (buckets[i] != NULL && buckets[i] != &deleted) {
uint32_t j, last;
last = newCapacity;
j = buckets[i]->hash & (newCapacity - 1);
for (; j < last && newBuckets[j] != NULL; j++);
/* In case the last bucket is already used */
if (j >= last) {
last = buckets[i]->hash & (newCapacity - 1);
for (j = 0; j < last &&
newBuckets[j] != NULL; j++);
}
assert(j < last);
newBuckets[j] = buckets[i];
}
}
[self freeMemory: buckets];
buckets = newBuckets;
capacity = newCapacity;
}
- (void)OF_setValue: (void*)value
forKey: (void*)key
hash: (uint32_t)hash
{
uint32_t i, last;
void *old;
if (key == NULL || value == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(hash, rotate);
last = capacity;
for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key))
break;
}
/* In case the last bucket is already used */
if (i >= last) {
last = hash & (capacity - 1);
for (i = 0; i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key))
break;
}
}
/* Key not in dictionary */
if (i >= last || buckets[i] == NULL || buckets[i] == &deleted ||
!keyFunctions.equal(buckets[i]->key, key)) {
struct of_map_table_bucket *bucket;
[self OF_resizeForCount: count + 1];
mutations++;
last = capacity;
for (i = hash & (capacity - 1); i < last &&
buckets[i] != NULL && buckets[i] != &deleted; i++);
/* In case the last bucket is already used */
if (i >= last) {
last = hash & (capacity - 1);
for (i = 0; i < last && buckets[i] != NULL &&
buckets[i] != &deleted; i++);
}
if (i >= last)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
bucket = [self allocMemoryWithSize: sizeof(*bucket)];
@try {
bucket->key = keyFunctions.retain(key);
} @catch (id e) {
[self freeMemory: bucket];
@throw e;
}
@try {
bucket->value = valueFunctions.retain(value);
} @catch (id e) {
keyFunctions.release(key);
[self freeMemory: bucket];
@throw e;
}
bucket->hash = hash;
buckets[i] = bucket;
count++;
return;
}
old = buckets[i]->value;
buckets[i]->value = valueFunctions.retain(value);
valueFunctions.release(old);
}
- (void)setValue: (void*)value
forKey: (void*)key
{
[self OF_setValue: value
forKey: key
hash: keyFunctions.hash(key)];
}
- (void)removeValueForKey: (void*)key
{
uint32_t i, hash, last;
if (key == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(keyFunctions.hash(key), rotate);
last = capacity;
for (i = hash & (capacity - 1); i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key)) {
keyFunctions.release(buckets[i]->key);
valueFunctions.release(buckets[i]->value);
[self freeMemory: buckets[i]];
buckets[i] = &deleted;
count--;
mutations++;
[self OF_resizeForCount: count];
return;
}
}
if (i < last)
return;
/* In case the last bucket is already used */
last = hash & (capacity - 1);
for (i = 0; i < last && buckets[i] != NULL; i++) {
if (buckets[i] == &deleted)
continue;
if (keyFunctions.equal(buckets[i]->key, key)) {
keyFunctions.release(buckets[i]->key);
valueFunctions.release(buckets[i]->value);
[self freeMemory: buckets[i]];
buckets[i] = &deleted;
count--;
mutations++;
[self OF_resizeForCount: count];
return;
}
}
}
- (BOOL)containsValue: (void*)value
{
uint32_t i;
if (value == NULL || count == 0)
return NO;
for (i = 0; i < capacity; i++)
if (buckets[i] != NULL && buckets[i] != &deleted)
if (valueFunctions.equal(buckets[i]->value, value))
return YES;
return NO;
}
- (BOOL)containsValueIdenticalTo: (void*)value
{
uint32_t i;
if (value == NULL || count == 0)
return NO;
for (i = 0; i < capacity; i++)
if (buckets[i] != NULL && buckets[i] != &deleted)
if (buckets[i]->value == value)
return YES;
return NO;
}
- (OFMapTableEnumerator*)keyEnumerator
{
return [[[OFMapTableKeyEnumerator alloc]
OF_initWithMapTable: self
buckets: buckets
capacity: capacity
mutationsPointer: &mutations] autorelease];
}
- (OFMapTableEnumerator*)valueEnumerator
{
return [[[OFMapTableValueEnumerator alloc]
OF_initWithMapTable: self
buckets: buckets
capacity: capacity
mutationsPointer: &mutations] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count_
{
uint32_t j = (uint32_t)state->state;
int i;
for (i = 0; i < count_; i++) {
for (; j < capacity && (buckets[j] == NULL ||
buckets[j] == &deleted); j++);
if (j < capacity) {
objects[i] = buckets[j]->key;
j++;
} else
break;
}
state->state = j;
state->itemsPtr = objects;
state->mutationsPtr = &mutations;
return i;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndValuesUsingBlock:
(of_map_table_enumeration_block_t)block
{
size_t i;
BOOL stop = NO;
unsigned long mutations_ = mutations;
for (i = 0; i < capacity && !stop; i++) {
if (mutations != mutations_)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
if (buckets[i] != NULL && buckets[i] != &deleted)
block(buckets[i]->key, buckets[i]->value, &stop);
}
}
- (void)replaceValuesUsingBlock: (of_map_table_replace_block_t)block
{
size_t i;
BOOL stop = NO;
unsigned long mutations_ = mutations;
for (i = 0; i < capacity && !stop; i++) {
if (mutations != mutations_)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
if (buckets[i] != NULL && buckets[i] != &deleted) {
void *old, *new;
new = block(buckets[i]->key, buckets[i]->value, &stop);
if (new == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
old = buckets[i]->value;
buckets[i]->value = valueFunctions.retain(new);
valueFunctions.release(old);
}
}
}
#endif
- (of_map_table_functions_t)keyFunctions
{
return keyFunctions;
}
- (of_map_table_functions_t)valueFunctions
{
return valueFunctions;
}
@end
@implementation OFMapTableEnumerator
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- OF_initWithMapTable: (OFMapTable*)mapTable_
buckets: (struct of_map_table_bucket**)buckets_
capacity: (uint32_t)capacity_
mutationsPointer: (unsigned long*)mutationsPtr_
{
self = [super init];
mapTable = [mapTable_ retain];
buckets = buckets_;
capacity = capacity_;
mutations = *mutationsPtr_;
mutationsPtr = mutationsPtr_;
return self;
}
- (void)dealloc
{
[mapTable release];
[super dealloc];
}
- (void*)nextValue
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)reset
{
if (*mutationsPtr != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [mapTable class]
object: mapTable];
position = 0;
}
@end
@implementation OFMapTableKeyEnumerator
- (void*)nextValue
{
if (*mutationsPtr != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [mapTable class]
object: mapTable];
for (; position < capacity && (buckets[position] == NULL ||
buckets[position] == &deleted); position++);
if (position < capacity)
return buckets[position++]->key;
else
return NULL;
}
@end
@implementation OFMapTableValueEnumerator
- (void*)nextValue
{
if (*mutationsPtr != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [mapTable class]
object: mapTable];
for (; position < capacity && (buckets[position] == NULL ||
buckets[position] == &deleted); position++);
if (position < capacity)
return buckets[position++]->value;
else
return NULL;
}
@end
@implementation OFMapTableEnumeratorWrapper
- initWithEnumerator: (OFMapTableEnumerator*)enumerator_
object: (id)object_
{
self = [super init];
enumerator = [enumerator_ retain];
object = [object_ retain];
return self;
}
- (void)dealloc
{
[enumerator release];
[object release];
[super dealloc];
}
- (id)nextObject
{
id ret;
@try {
ret = [enumerator nextValue];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [object class]
object: object];
}
return ret;
}
- (void)reset
{
@try {
[enumerator reset];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [object class]
object: object];
}
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
|
[self release];
@throw e;
}
abort();
}
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions
valueFunctions: (of_map_table_functions_t)valueFunctions
{
return [self initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: 0];
}
- initWithKeyFunctions: (of_map_table_functions_t)keyFunctions
valueFunctions: (of_map_table_functions_t)valueFunctions
capacity: (size_t)capacity
{
self = [super init];
@try {
_keyFunctions = keyFunctions;
_valueFunctions = valueFunctions;
#define SET_DEFAULT(var, value) \
if (var == NULL) \
var = value;
SET_DEFAULT(_keyFunctions.retain, default_retain);
SET_DEFAULT(_keyFunctions.release, default_release);
SET_DEFAULT(_keyFunctions.hash, default_hash);
SET_DEFAULT(_keyFunctions.equal, default_equal);
SET_DEFAULT(_valueFunctions.retain, default_retain);
SET_DEFAULT(_valueFunctions.release, default_release);
SET_DEFAULT(_valueFunctions.hash, default_hash);
SET_DEFAULT(_valueFunctions.equal, default_equal);
#undef SET_DEFAULT
if (capacity > UINT32_MAX ||
capacity > UINT32_MAX / sizeof(*_buckets) ||
capacity > UINT32_MAX / 8)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
for (_capacity = 1; _capacity < capacity; _capacity <<= 1);
if (capacity * 8 / _capacity >= 6)
_capacity <<= 1;
if (_capacity < MIN_CAPACITY)
_capacity = MIN_CAPACITY;
_minCapacity = _capacity;
_buckets = [self allocMemoryWithSize: sizeof(*_buckets)
count: _capacity];
memset(_buckets, 0, _capacity * sizeof(*_buckets));
if (of_hash_seed != 0)
#if defined(HAVE_ARC4RANDOM)
_rotate = arc4random() & 31;
#elif defined(HAVE_RANDOM)
_rotate = random() & 31;
#else
_rotate = rand() & 31;
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
uint32_t i;
for (i = 0; i < _capacity; i++) {
if (_buckets[i] != NULL && _buckets[i] != &deleted) {
_keyFunctions.release(_buckets[i]->key);
_valueFunctions.release(_buckets[i]->value);
}
}
[super dealloc];
}
- (BOOL)isEqual: (id)object
{
OFMapTable *mapTable;
uint32_t i;
if (![object isKindOfClass: [OFMapTable class]])
return NO;
mapTable = object;
if (mapTable->_count != _count ||
mapTable->_keyFunctions.equal != _keyFunctions.equal ||
mapTable->_valueFunctions.equal != _valueFunctions.equal)
return NO;
for (i = 0; i < _capacity; i++) {
if (_buckets[i] != NULL && _buckets[i] != &deleted) {
void *value = [mapTable valueForKey: _buckets[i]->key];
if (!_valueFunctions.equal(value, _buckets[i]->value))
return NO;
}
}
return YES;
}
- (uint32_t)hash
{
uint32_t i, hash = 0;
for (i = 0; i < _capacity; i++) {
if (_buckets[i] != NULL && _buckets[i] != &deleted) {
hash += OF_ROR(_buckets[i]->hash, _rotate);
hash += _valueFunctions.hash(_buckets[i]->value);
}
}
return hash;
}
- (id)copy
{
OFMapTable *copy = [[OFMapTable alloc]
initWithKeyFunctions: _keyFunctions
valueFunctions: _valueFunctions
capacity: _capacity];
@try {
uint32_t i;
for (i = 0; i < _capacity; i++)
if (_buckets[i] != NULL && _buckets[i] != &deleted)
[copy OF_setValue: _buckets[i]->value
forKey: _buckets[i]->key
hash: OF_ROR(_buckets[i]->hash,
_rotate)];
} @catch (id e) {
[copy release];
@throw e;
}
copy->_minCapacity = MIN_CAPACITY;
return copy;
}
- (size_t)count
{
return _count;
}
- (void*)valueForKey: (void*)key
{
uint32_t i, hash, last;
if (key == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(_keyFunctions.hash(key), _rotate);
last = _capacity;
for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key))
return _buckets[i]->value;
}
if (i < last)
return nil;
/* In case the last bucket is already used */
last = hash & (_capacity - 1);
for (i = 0; i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key))
return _buckets[i]->value;
}
return NULL;
}
- (void)OF_resizeForCount: (uint32_t)count
{
uint32_t i, fullness, capacity;
struct of_map_table_bucket **buckets;
if (count > UINT32_MAX || count > UINT32_MAX / sizeof(*_buckets) ||
count > UINT32_MAX / 8)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
fullness = count * 8 / _capacity;
if (fullness >= 6)
capacity = _capacity << 1;
else if (fullness <= 1)
capacity = _capacity >> 1;
else
return;
if (capacity < _capacity && capacity < _minCapacity)
return;
buckets = [self allocMemoryWithSize: sizeof(*buckets)
count: capacity];
for (i = 0; i < capacity; i++)
buckets[i] = NULL;
for (i = 0; i < _capacity; i++) {
if (_buckets[i] != NULL && _buckets[i] != &deleted) {
uint32_t j, last;
last = capacity;
j = _buckets[i]->hash & (capacity - 1);
for (; j < last && buckets[j] != NULL; j++);
/* In case the last bucket is already used */
if (j >= last) {
last = _buckets[i]->hash & (capacity - 1);
for (j = 0; j < last &&
buckets[j] != NULL; j++);
}
assert(j < last);
buckets[j] = _buckets[i];
}
}
[self freeMemory: _buckets];
_buckets = buckets;
_capacity = capacity;
}
- (void)OF_setValue: (void*)value
forKey: (void*)key
hash: (uint32_t)hash
{
uint32_t i, last;
void *old;
if (key == NULL || value == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(hash, _rotate);
last = _capacity;
for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key))
break;
}
/* In case the last bucket is already used */
if (i >= last) {
last = hash & (_capacity - 1);
for (i = 0; i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key))
break;
}
}
/* Key not in dictionary */
if (i >= last || _buckets[i] == NULL || _buckets[i] == &deleted ||
!_keyFunctions.equal(_buckets[i]->key, key)) {
struct of_map_table_bucket *bucket;
[self OF_resizeForCount: _count + 1];
_mutations++;
last = _capacity;
for (i = hash & (_capacity - 1); i < last &&
_buckets[i] != NULL && _buckets[i] != &deleted; i++);
/* In case the last bucket is already used */
if (i >= last) {
last = hash & (_capacity - 1);
for (i = 0; i < last && _buckets[i] != NULL &&
_buckets[i] != &deleted; i++);
}
if (i >= last)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
bucket = [self allocMemoryWithSize: sizeof(*bucket)];
@try {
bucket->key = _keyFunctions.retain(key);
} @catch (id e) {
[self freeMemory: bucket];
@throw e;
}
@try {
bucket->value = _valueFunctions.retain(value);
} @catch (id e) {
_keyFunctions.release(key);
[self freeMemory: bucket];
@throw e;
}
bucket->hash = hash;
_buckets[i] = bucket;
_count++;
return;
}
old = _buckets[i]->value;
_buckets[i]->value = _valueFunctions.retain(value);
_valueFunctions.release(old);
}
- (void)setValue: (void*)value
forKey: (void*)key
{
[self OF_setValue: value
forKey: key
hash: _keyFunctions.hash(key)];
}
- (void)removeValueForKey: (void*)key
{
uint32_t i, hash, last;
if (key == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
hash = OF_ROL(_keyFunctions.hash(key), _rotate);
last = _capacity;
for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key)) {
_keyFunctions.release(_buckets[i]->key);
_valueFunctions.release(_buckets[i]->value);
[self freeMemory: _buckets[i]];
_buckets[i] = &deleted;
_count--;
_mutations++;
[self OF_resizeForCount: _count];
return;
}
}
if (i < last)
return;
/* In case the last bucket is already used */
last = hash & (_capacity - 1);
for (i = 0; i < last && _buckets[i] != NULL; i++) {
if (_buckets[i] == &deleted)
continue;
if (_keyFunctions.equal(_buckets[i]->key, key)) {
_keyFunctions.release(_buckets[i]->key);
_valueFunctions.release(_buckets[i]->value);
[self freeMemory: _buckets[i]];
_buckets[i] = &deleted;
_count--;
_mutations++;
[self OF_resizeForCount: _count];
return;
}
}
}
- (BOOL)containsValue: (void*)value
{
uint32_t i;
if (value == NULL || _count == 0)
return NO;
for (i = 0; i < _capacity; i++)
if (_buckets[i] != NULL && _buckets[i] != &deleted)
if (_valueFunctions.equal(_buckets[i]->value, value))
return YES;
return NO;
}
- (BOOL)containsValueIdenticalTo: (void*)value
{
uint32_t i;
if (value == NULL || _count == 0)
return NO;
for (i = 0; i < _capacity; i++)
if (_buckets[i] != NULL && _buckets[i] != &deleted)
if (_buckets[i]->value == value)
return YES;
return NO;
}
- (OFMapTableEnumerator*)keyEnumerator
{
return [[[OFMapTableKeyEnumerator alloc]
OF_initWithMapTable: self
buckets: _buckets
capacity: _capacity
mutationsPointer: &_mutations] autorelease];
}
- (OFMapTableEnumerator*)valueEnumerator
{
return [[[OFMapTableValueEnumerator alloc]
OF_initWithMapTable: self
buckets: _buckets
capacity: _capacity
mutationsPointer: &_mutations] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count
{
uint32_t j = (uint32_t)state->state;
int i;
for (i = 0; i < count; i++) {
for (; j < _capacity && (_buckets[j] == NULL ||
_buckets[j] == &deleted); j++);
if (j < _capacity) {
objects[i] = _buckets[j]->key;
j++;
} else
break;
}
state->state = j;
state->itemsPtr = objects;
state->mutationsPtr = &_mutations;
return i;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateKeysAndValuesUsingBlock:
(of_map_table_enumeration_block_t)block
{
size_t i;
BOOL stop = NO;
unsigned long mutations = _mutations;
for (i = 0; i < _capacity && !stop; i++) {
if (_mutations != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
if (_buckets[i] != NULL && _buckets[i] != &deleted)
block(_buckets[i]->key, _buckets[i]->value, &stop);
}
}
- (void)replaceValuesUsingBlock: (of_map_table_replace_block_t)block
{
size_t i;
BOOL stop = NO;
unsigned long mutations = _mutations;
for (i = 0; i < _capacity && !stop; i++) {
if (_mutations != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
if (_buckets[i] != NULL && _buckets[i] != &deleted) {
void *old, *new;
new = block(_buckets[i]->key, _buckets[i]->value,
&stop);
if (new == NULL)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
old = _buckets[i]->value;
_buckets[i]->value = _valueFunctions.retain(new);
_valueFunctions.release(old);
}
}
}
#endif
- (of_map_table_functions_t)keyFunctions
{
return _keyFunctions;
}
- (of_map_table_functions_t)valueFunctions
{
return _valueFunctions;
}
@end
@implementation OFMapTableEnumerator
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- OF_initWithMapTable: (OFMapTable*)mapTable
buckets: (struct of_map_table_bucket**)buckets
capacity: (uint32_t)capacity
mutationsPointer: (unsigned long*)mutationsPtr
{
self = [super init];
_mapTable = [mapTable retain];
_buckets = buckets;
_capacity = capacity;
_mutations = *mutationsPtr;
_mutationsPtr = mutationsPtr;
return self;
}
- (void)dealloc
{
[_mapTable release];
[super dealloc];
}
- (void*)nextValue
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)reset
{
if (*_mutationsPtr != _mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [_mapTable class]
object: _mapTable];
_position = 0;
}
@end
@implementation OFMapTableKeyEnumerator
- (void*)nextValue
{
if (*_mutationsPtr != _mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [_mapTable class]
object: _mapTable];
for (; _position < _capacity && (_buckets[_position] == NULL ||
_buckets[_position] == &deleted); _position++);
if (_position < _capacity)
return _buckets[_position++]->key;
else
return NULL;
}
@end
@implementation OFMapTableValueEnumerator
- (void*)nextValue
{
if (*_mutationsPtr != _mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [_mapTable class]
object: _mapTable];
for (; _position < _capacity && (_buckets[_position] == NULL ||
_buckets[_position] == &deleted); _position++);
if (_position < _capacity)
return _buckets[_position++]->value;
else
return NULL;
}
@end
@implementation OFMapTableEnumeratorWrapper
- initWithEnumerator: (OFMapTableEnumerator*)enumerator
object: (id)object
{
self = [super init];
_enumerator = [enumerator retain];
_object = [object retain];
return self;
}
- (void)dealloc
{
[_enumerator release];
[_object release];
[super dealloc];
}
- (id)nextObject
{
id ret;
@try {
ret = [_enumerator nextValue];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [_object class]
object: _object];
}
return ret;
}
- (void)reset
{
@try {
[_enumerator reset];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [_object class]
object: _object];
}
}
@end
|
Modified src/OFMutableArray_adjacent.h
from [9fe27a2082]
to [b092493c38].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFArray.h"
@class OFDataArray;
@interface OFMutableArray_adjacent: OFMutableArray
{
OFDataArray *array;
unsigned long mutations;
}
@end
|
|
|
|
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFArray.h"
@class OFDataArray;
@interface OFMutableArray_adjacent: OFMutableArray
{
OFDataArray *_array;
unsigned long _mutations;
}
@end
|
Modified src/OFMutableArray_adjacent.m
from [0727c1b670]
to [65e0f02167].
︙ | | | ︙ | |
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
|
- (void)addObject: (id)object
{
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[array addItem: &object];
[object retain];
mutations++;
}
- (void)insertObject: (id)object
atIndex: (size_t)index
{
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[array insertItem: &object
atIndex: index];
[object retain];
mutations++;
}
- (void)insertObjectsFromArray: (OFArray*)array_
atIndex: (size_t)index
{
id *objects = [array_ objects];
size_t i, count = [array_ count];
[array insertItems: objects
atIndex: index
count: count];
for (i = 0; i < count; i++)
[objects[i] retain];
mutations++;
}
- (void)replaceObject: (id)oldObject
withObject: (id)newObject
{
id *objects;
size_t i, count;
if (oldObject == nil || newObject == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [array items];
count = [array count];
for (i = 0; i < count; i++) {
if ([objects[i] isEqual: oldObject]) {
[newObject retain];
[objects[i] release];
objects[i] = newObject;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
- (void)addObject: (id)object
{
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[_array addItem: &object];
[object retain];
_mutations++;
}
- (void)insertObject: (id)object
atIndex: (size_t)index
{
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
[_array insertItem: &object
atIndex: index];
[object retain];
_mutations++;
}
- (void)insertObjectsFromArray: (OFArray*)array
atIndex: (size_t)index
{
id *objects = [array objects];
size_t i, count = [array count];
[_array insertItems: objects
atIndex: index
count: count];
for (i = 0; i < count; i++)
[objects[i] retain];
_mutations++;
}
- (void)replaceObject: (id)oldObject
withObject: (id)newObject
{
id *objects;
size_t i, count;
if (oldObject == nil || newObject == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++) {
if ([objects[i] isEqual: oldObject]) {
[newObject retain];
[objects[i] release];
objects[i] = newObject;
|
︙ | | | ︙ | |
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
id *objects;
id oldObject;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [array items];
if (index >= [array count])
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
oldObject = objects[index];
objects[index] = [object retain];
[oldObject release];
}
- (void)replaceObjectIdenticalTo: (id)oldObject
withObject: (id)newObject
{
id *objects;
size_t i, count;
if (oldObject == nil || newObject == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [array items];
count = [array count];
for (i = 0; i < count; i++) {
if (objects[i] == oldObject) {
[newObject retain];
[objects[i] release];
objects[i] = newObject;
|
|
|
|
|
|
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
id *objects;
id oldObject;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [_array items];
if (index >= [_array count])
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
oldObject = objects[index];
objects[index] = [object retain];
[oldObject release];
}
- (void)replaceObjectIdenticalTo: (id)oldObject
withObject: (id)newObject
{
id *objects;
size_t i, count;
if (oldObject == nil || newObject == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++) {
if (objects[i] == oldObject) {
[newObject retain];
[objects[i] release];
objects[i] = newObject;
|
︙ | | | ︙ | |
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
id *objects;
size_t i, count;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [array items];
count = [array count];
for (i = 0; i < count; i++) {
if ([objects[i] isEqual: object]) {
object = objects[i];
[array removeItemAtIndex: i];
mutations++;
[object release];
return;
}
}
}
- (void)removeObjectIdenticalTo: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [array items];
count = [array count];
for (i = 0; i < count; i++) {
if (objects[i] == object) {
[array removeItemAtIndex: i];
mutations++;
[object release];
return;
}
}
}
- (void)removeObjectAtIndex: (size_t)index
{
id object = [self objectAtIndex: index];
[array removeItemAtIndex: index];
[object release];
mutations++;
}
- (void)removeAllObjects
{
id *objects = [array items];
size_t i, count = [array count];
for (i = 0; i < count; i++)
[objects[i] release];
[array removeAllItems];
}
- (void)removeObjectsInRange: (of_range_t)range
{
id *objects = [array items], *copy;
size_t i, count = [array count];
if (range.length > SIZE_MAX - range.location ||
range.length > count - range.location)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
copy = [self allocMemoryWithSize: sizeof(*copy)
count: range.length];
memcpy(copy, objects + range.location, range.length * sizeof(id));
@try {
[array removeItemsInRange: range];
mutations++;
for (i = 0; i < range.length; i++)
[copy[i] release];
} @finally {
[self freeMemory: copy];
}
}
- (void)removeLastObject
{
size_t count = [array count];
id object;
if (count == 0)
return;
object = [self objectAtIndex: count - 1];
[array removeLastItem];
[object release];
mutations++;
}
- (void)exchangeObjectAtIndex: (size_t)index1
withObjectAtIndex: (size_t)index2
{
id *objects = [array items];
size_t count = [array count];
id tmp;
if (index1 >= count || index2 >= count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
tmp = objects[index1];
objects[index1] = objects[index2];
objects[index2] = tmp;
}
- (void)reverse
{
id *objects = [array items];
size_t i, j, count = [array count];
if (count == 0 || count == 1)
return;
for (i = 0, j = count - 1; i < j; i++, j--) {
id tmp = objects[i];
objects[i] = objects[j];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
id *objects;
size_t i, count;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++) {
if ([objects[i] isEqual: object]) {
object = objects[i];
[_array removeItemAtIndex: i];
_mutations++;
[object release];
return;
}
}
}
- (void)removeObjectIdenticalTo: (id)object
{
id *objects;
size_t i, count;
if (object == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
objects = [_array items];
count = [_array count];
for (i = 0; i < count; i++) {
if (objects[i] == object) {
[_array removeItemAtIndex: i];
_mutations++;
[object release];
return;
}
}
}
- (void)removeObjectAtIndex: (size_t)index
{
id object = [self objectAtIndex: index];
[_array removeItemAtIndex: index];
[object release];
_mutations++;
}
- (void)removeAllObjects
{
id *objects = [_array items];
size_t i, count = [_array count];
for (i = 0; i < count; i++)
[objects[i] release];
[_array removeAllItems];
}
- (void)removeObjectsInRange: (of_range_t)range
{
id *objects = [_array items], *copy;
size_t i, count = [_array count];
if (range.length > SIZE_MAX - range.location ||
range.length > count - range.location)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
copy = [self allocMemoryWithSize: sizeof(*copy)
count: range.length];
memcpy(copy, objects + range.location, range.length * sizeof(id));
@try {
[_array removeItemsInRange: range];
_mutations++;
for (i = 0; i < range.length; i++)
[copy[i] release];
} @finally {
[self freeMemory: copy];
}
}
- (void)removeLastObject
{
size_t count = [_array count];
id object;
if (count == 0)
return;
object = [self objectAtIndex: count - 1];
[_array removeLastItem];
[object release];
_mutations++;
}
- (void)exchangeObjectAtIndex: (size_t)index1
withObjectAtIndex: (size_t)index2
{
id *objects = [_array items];
size_t count = [_array count];
id tmp;
if (index1 >= count || index2 >= count)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
tmp = objects[index1];
objects[index1] = objects[index2];
objects[index2] = tmp;
}
- (void)reverse
{
id *objects = [_array items];
size_t i, j, count = [_array count];
if (count == 0 || count == 1)
return;
for (i = 0, j = count - 1; i < j; i++, j--) {
id tmp = objects[i];
objects[i] = objects[j];
|
︙ | | | ︙ | |
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
* does not reimplement it. As OFArray_adjacent does not reimplement it
* either, this is fine.
*/
int ret = [super countByEnumeratingWithState: state
objects: objects
count: count];
state->mutationsPtr = &mutations;
return ret;
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFArrayEnumerator alloc]
initWithArray: self
mutationsPtr: &mutations] autorelease];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [array items];
size_t i, count = [array count];
BOOL stop = NO;
unsigned long mutations_ = mutations;
for (i = 0; i < count && !stop; i++) {
if (mutations != mutations_)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
block(objects[i], i, &stop);
}
}
- (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
{
id *objects = [array items];
size_t i, count = [array count];
BOOL stop = NO;
unsigned long mutations_ = mutations;
for (i = 0; i < count && !stop; i++) {
id newObject;
if (mutations != mutations_)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
newObject = block(objects[i], i, &stop);
if (newObject == nil)
|
|
|
|
|
|
|
|
|
|
|
|
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
* does not reimplement it. As OFArray_adjacent does not reimplement it
* either, this is fine.
*/
int ret = [super countByEnumeratingWithState: state
objects: objects
count: count];
state->mutationsPtr = &_mutations;
return ret;
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFArrayEnumerator alloc]
initWithArray: self
mutationsPtr: &_mutations] autorelease];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_array_enumeration_block_t)block
{
id *objects = [_array items];
size_t i, count = [_array count];
BOOL stop = NO;
unsigned long mutations = _mutations;
for (i = 0; i < count && !stop; i++) {
if (_mutations != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
block(objects[i], i, &stop);
}
}
- (void)replaceObjectsUsingBlock: (of_array_replace_block_t)block
{
id *objects = [_array items];
size_t i, count = [_array count];
BOOL stop = NO;
unsigned long mutations = _mutations;
for (i = 0; i < count && !stop; i++) {
id newObject;
if (_mutations != mutations)
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
newObject = block(objects[i], i, &stop);
if (newObject == nil)
|
︙ | | | ︙ | |
Modified src/OFMutableDictionary_hashtable.h
from [e5615bdea0]
to [6850c24dfd].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
|
#import "OFDictionary.h"
@class OFMapTable;
@interface OFMutableDictionary_hashtable: OFMutableDictionary
{
OFMapTable *mapTable;
}
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
|
#import "OFDictionary.h"
@class OFMapTable;
@interface OFMutableDictionary_hashtable: OFMutableDictionary
{
OFMapTable *_mapTable;
}
@end
|
Modified src/OFMutableDictionary_hashtable.m
from [612f34358f]
to [808b6f21ab].
︙ | | | ︙ | |
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
|
if (self == [OFMutableDictionary_hashtable class])
[self inheritMethodsFromClass: [OFDictionary_hashtable class]];
}
- (void)setObject: (id)object
forKey: (id)key
{
[mapTable setValue: object
forKey: key];
}
- (void)removeObjectForKey: (id)key
{
[mapTable removeValueForKey: key];
}
#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block
{
@try {
[mapTable replaceValuesUsingBlock:
^ void* (void *key, void *value, BOOL *stop) {
return block(key, value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
|
|
|
|
|
|
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
|
if (self == [OFMutableDictionary_hashtable class])
[self inheritMethodsFromClass: [OFDictionary_hashtable class]];
}
- (void)setObject: (id)object
forKey: (id)key
{
[_mapTable setValue: object
forKey: key];
}
- (void)removeObjectForKey: (id)key
{
[_mapTable removeValueForKey: key];
}
#ifdef OF_HAVE_BLOCKS
- (void)replaceObjectsUsingBlock: (of_dictionary_replace_block_t)block
{
@try {
[_mapTable replaceValuesUsingBlock:
^ void* (void *key, void *value, BOOL *stop) {
return block(key, value, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
|
︙ | | | ︙ | |
Modified src/OFMutableSet_hashtable.h
from [429d954c17]
to [7dc73c5a43].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
|
#import "OFMutableSet.h"
@class OFMapTable;
@interface OFMutableSet_hashtable: OFMutableSet
{
OFMapTable *mapTable;
}
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
|
#import "OFMutableSet.h"
@class OFMapTable;
@interface OFMutableSet_hashtable: OFMutableSet
{
OFMapTable *_mapTable;
}
@end
|
Modified src/OFMutableSet_hashtable.m
from [be12d7d85e]
to [f03acdef2a].
︙ | | | ︙ | |
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
{
if (self == [OFMutableSet_hashtable class])
[self inheritMethodsFromClass: [OFSet_hashtable class]];
}
- (void)addObject: (id)object
{
[mapTable setValue: (void*)1
forKey: object];
}
- (void)removeObject: (id)object
{
[mapTable removeValueForKey: object];
}
- (void)makeImmutable
{
object_setClass(self, [OFSet_hashtable class]);
}
@end
|
|
|
|
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
{
if (self == [OFMutableSet_hashtable class])
[self inheritMethodsFromClass: [OFSet_hashtable class]];
}
- (void)addObject: (id)object
{
[_mapTable setValue: (void*)1
forKey: object];
}
- (void)removeObject: (id)object
{
[_mapTable removeValueForKey: object];
}
- (void)makeImmutable
{
object_setClass(self, [OFSet_hashtable class]);
}
@end
|
Modified src/OFMutableString_UTF8.h
from [24f2d8f550]
to [7d75f5d24d].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFMutableString.h"
#import "OFString_UTF8.h"
@interface OFMutableString_UTF8: OFMutableString
{
@public
struct of_string_utf8_ivars *restrict s;
struct of_string_utf8_ivars s_store;
}
@end
|
|
|
|
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFMutableString.h"
#import "OFString_UTF8.h"
@interface OFMutableString_UTF8: OFMutableString
{
@public
struct of_string_utf8_ivars *restrict _s;
struct of_string_utf8_ivars _storage;
}
@end
|
Modified src/OFMutableString_UTF8.m
from [3edda5e667]
to [8a8377795b].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
{
of_unichar_t *unicodeString;
size_t unicodeLen, newCStringLength;
size_t i, j;
char *newCString;
BOOL isStart = YES;
if (!s->isUTF8) {
uint8_t t;
const of_unichar_t *const *table;
assert(startTableSize >= 1 && middleTableSize >= 1);
s->hashed = NO;
for (i = 0; i < s->cStringLength; i++) {
if (isStart)
table = startTable;
else
table = middleTable;
switch (s->cString[i]) {
case ' ':
case '\t':
case '\n':
case '\r':
isStart = YES;
break;
default:
isStart = NO;
break;
}
if ((t = table[0][(uint8_t)s->cString[i]]) != 0)
s->cString[i] = t;
}
return;
}
unicodeLen = [self length];
unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t)
count: unicodeLen];
i = j = 0;
newCStringLength = 0;
while (i < s->cStringLength) {
const of_unichar_t *const *table;
size_t tableSize;
of_unichar_t c;
size_t cLen;
if (isStart) {
table = startTable;
tableSize = middleTableSize;
} else {
table = middleTable;
tableSize = middleTableSize;
}
cLen = of_string_utf8_decode(s->cString + i,
s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF) {
[self freeMemory: unicodeString];
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
{
of_unichar_t *unicodeString;
size_t unicodeLen, newCStringLength;
size_t i, j;
char *newCString;
BOOL isStart = YES;
if (!_s->isUTF8) {
uint8_t t;
const of_unichar_t *const *table;
assert(startTableSize >= 1 && middleTableSize >= 1);
_s->hashed = NO;
for (i = 0; i < _s->cStringLength; i++) {
if (isStart)
table = startTable;
else
table = middleTable;
switch (_s->cString[i]) {
case ' ':
case '\t':
case '\n':
case '\r':
isStart = YES;
break;
default:
isStart = NO;
break;
}
if ((t = table[0][(uint8_t)_s->cString[i]]) != 0)
_s->cString[i] = t;
}
return;
}
unicodeLen = [self length];
unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t)
count: unicodeLen];
i = j = 0;
newCStringLength = 0;
while (i < _s->cStringLength) {
const of_unichar_t *const *table;
size_t tableSize;
of_unichar_t c;
size_t cLen;
if (isStart) {
table = startTable;
tableSize = middleTableSize;
} else {
table = middleTable;
tableSize = middleTableSize;
}
cLen = of_string_utf8_decode(_s->cString + i,
_s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF) {
[self freeMemory: unicodeString];
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
|
︙ | | | ︙ | |
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
j += d;
}
assert(j == newCStringLength);
newCString[j] = 0;
[self freeMemory: unicodeString];
[self freeMemory: s->cString];
s->hashed = NO;
s->cString = newCString;
s->cStringLength = newCStringLength;
/*
* Even though cStringLength can change, length cannot, therefore no
* need to change it.
*/
}
- (void)setCharacter: (of_unichar_t)character
atIndex: (size_t)index
{
char buffer[4];
of_unichar_t c;
size_t lenNew, lenOld;
if (s->isUTF8)
index = of_string_utf8_get_position(s->cString, index,
s->cStringLength);
if (index > s->cStringLength)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
/* Shortcut if old and new character both are ASCII */
if (!(character & 0x80) && !(s->cString[index] & 0x80)) {
s->hashed = NO;
s->cString[index] = character;
return;
}
if ((lenNew = of_string_utf8_encode(character, buffer)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
if ((lenOld = of_string_utf8_decode(s->cString + index,
s->cStringLength - index, &c)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
s->hashed = NO;
if (lenNew == lenOld)
memcpy(s->cString + index, buffer, lenNew);
else if (lenNew > lenOld) {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength -
lenOld + lenNew + 1];
memmove(s->cString + index + lenNew,
s->cString + index + lenOld,
s->cStringLength - index - lenOld);
memcpy(s->cString + index, buffer, lenNew);
s->cStringLength -= lenOld;
s->cStringLength += lenNew;
s->cString[s->cStringLength] = '\0';
if (character & 0x80)
s->isUTF8 = YES;
} else if (lenNew < lenOld) {
memmove(s->cString + index + lenNew,
s->cString + index + lenOld,
s->cStringLength - index - lenOld);
memcpy(s->cString + index, buffer, lenNew);
s->cStringLength -= lenOld;
s->cStringLength += lenNew;
s->cString[s->cStringLength] = '\0';
@try {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
} else
assert(0);
}
- (void)appendUTF8String: (const char*)UTF8String
{
size_t UTF8StringLength = strlen(UTF8String);
size_t length;
if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
case 1:
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: s->cStringLength +
UTF8StringLength + 1];
memcpy(s->cString + s->cStringLength, UTF8String, UTF8StringLength + 1);
s->cStringLength += UTF8StringLength;
s->length += length;
}
- (void)appendUTF8String: (const char*)UTF8String
length: (size_t)UTF8StringLength
{
size_t length;
if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
case 1:
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: s->cStringLength +
UTF8StringLength + 1];
memcpy(s->cString + s->cStringLength, UTF8String, UTF8StringLength);
s->cStringLength += UTF8StringLength;
s->length += length;
s->cString[s->cStringLength] = 0;
}
- (void)appendCString: (const char*)cString
encoding: (of_string_encoding_t)encoding
{
return [self appendCString: cString
encoding: encoding
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
|
j += d;
}
assert(j == newCStringLength);
newCString[j] = 0;
[self freeMemory: unicodeString];
[self freeMemory: _s->cString];
_s->hashed = NO;
_s->cString = newCString;
_s->cStringLength = newCStringLength;
/*
* Even though cStringLength can change, length cannot, therefore no
* need to change it.
*/
}
- (void)setCharacter: (of_unichar_t)character
atIndex: (size_t)index
{
char buffer[4];
of_unichar_t c;
size_t lenNew, lenOld;
if (_s->isUTF8)
index = of_string_utf8_get_position(_s->cString, index,
_s->cStringLength);
if (index > _s->cStringLength)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
/* Shortcut if old and new character both are ASCII */
if (!(character & 0x80) && !(_s->cString[index] & 0x80)) {
_s->hashed = NO;
_s->cString[index] = character;
return;
}
if ((lenNew = of_string_utf8_encode(character, buffer)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
if ((lenOld = of_string_utf8_decode(_s->cString + index,
_s->cStringLength - index, &c)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
_s->hashed = NO;
if (lenNew == lenOld)
memcpy(_s->cString + index, buffer, lenNew);
else if (lenNew > lenOld) {
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength -
lenOld + lenNew + 1];
memmove(_s->cString + index + lenNew,
_s->cString + index + lenOld,
_s->cStringLength - index - lenOld);
memcpy(_s->cString + index, buffer, lenNew);
_s->cStringLength -= lenOld;
_s->cStringLength += lenNew;
_s->cString[_s->cStringLength] = '\0';
if (character & 0x80)
_s->isUTF8 = YES;
} else if (lenNew < lenOld) {
memmove(_s->cString + index + lenNew,
_s->cString + index + lenOld,
_s->cStringLength - index - lenOld);
memcpy(_s->cString + index, buffer, lenNew);
_s->cStringLength -= lenOld;
_s->cStringLength += lenNew;
_s->cString[_s->cStringLength] = '\0';
@try {
_s->cString = [self
resizeMemory: _s->cString
size: _s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
} else
assert(0);
}
- (void)appendUTF8String: (const char*)UTF8String
{
size_t UTF8StringLength = strlen(UTF8String);
size_t length;
if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
case 1:
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength +
UTF8StringLength + 1];
memcpy(_s->cString + _s->cStringLength, UTF8String,
UTF8StringLength + 1);
_s->cStringLength += UTF8StringLength;
_s->length += length;
}
- (void)appendUTF8String: (const char*)UTF8String
length: (size_t)UTF8StringLength
{
size_t length;
if (UTF8StringLength >= 3 && !memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
switch (of_string_utf8_check(UTF8String, UTF8StringLength, &length)) {
case 1:
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength +
UTF8StringLength + 1];
memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength);
_s->cStringLength += UTF8StringLength;
_s->length += length;
_s->cString[_s->cStringLength] = 0;
}
- (void)appendCString: (const char*)cString
encoding: (of_string_encoding_t)encoding
{
return [self appendCString: cString
encoding: encoding
|
︙ | | | ︙ | |
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
if (string == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
UTF8StringLength = [string UTF8StringLength];
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: s->cStringLength +
UTF8StringLength + 1];
memcpy(s->cString + s->cStringLength, [string UTF8String],
UTF8StringLength);
s->cStringLength += UTF8StringLength;
s->length += [string length];
s->cString[s->cStringLength] = 0;
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]]) {
if (((OFString_UTF8*)string)->s->isUTF8)
s->isUTF8 = YES;
} else
s->isUTF8 = YES;
}
- (void)appendCharacters: (of_unichar_t*)characters
length: (size_t)length
{
char *tmp;
|
|
|
|
|
|
|
|
|
|
|
|
|
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
if (string == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
UTF8StringLength = [string UTF8StringLength];
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength +
UTF8StringLength + 1];
memcpy(_s->cString + _s->cStringLength, [string UTF8String],
UTF8StringLength);
_s->cStringLength += UTF8StringLength;
_s->length += [string length];
_s->cString[_s->cStringLength] = 0;
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]]) {
if (((OFString_UTF8*)string)->_s->isUTF8)
_s->isUTF8 = YES;
} else
_s->isUTF8 = YES;
}
- (void)appendCharacters: (of_unichar_t*)characters
length: (size_t)length
{
char *tmp;
|
︙ | | | ︙ | |
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
|
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
tmp[j] = '\0';
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + j + 1];
memcpy(s->cString + s->cStringLength, tmp, j + 1);
s->cStringLength += j;
s->length += length;
if (isUTF8)
s->isUTF8 = YES;
} @finally {
[self freeMemory: tmp];
}
}
- (void)appendFormat: (OFConstantString*)format
arguments: (va_list)arguments
|
|
|
|
|
|
|
|
|
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
|
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
tmp[j] = '\0';
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength + j + 1];
memcpy(_s->cString + _s->cStringLength, tmp, j + 1);
_s->cStringLength += j;
_s->length += length;
if (isUTF8)
_s->isUTF8 = YES;
} @finally {
[self freeMemory: tmp];
}
}
- (void)appendFormat: (OFConstantString*)format
arguments: (va_list)arguments
|
︙ | | | ︙ | |
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
|
}
}
- (void)reverse
{
size_t i, j;
s->hashed = NO;
/* We reverse all bytes and restore UTF-8 later, if necessary */
for (i = 0, j = s->cStringLength - 1; i < s->cStringLength / 2;
i++, j--) {
s->cString[i] ^= s->cString[j];
s->cString[j] ^= s->cString[i];
s->cString[i] ^= s->cString[j];
}
if (!s->isUTF8)
return;
for (i = 0; i < s->cStringLength; i++) {
/* ASCII */
if OF_LIKELY (!(s->cString[i] & 0x80))
continue;
/* A start byte can't happen first as we reversed everything */
if OF_UNLIKELY (s->cString[i] & 0x40)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Next byte must not be ASCII */
if OF_UNLIKELY (s->cStringLength < i + 1 ||
!(s->cString[i + 1] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Next byte is the start byte */
if OF_LIKELY (s->cString[i + 1] & 0x40) {
s->cString[i] ^= s->cString[i + 1];
s->cString[i + 1] ^= s->cString[i];
s->cString[i] ^= s->cString[i + 1];
i++;
continue;
}
/* Second next byte must not be ASCII */
if OF_UNLIKELY (s->cStringLength < i + 2 ||
!(s->cString[i + 2] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Second next byte is the start byte */
if OF_LIKELY (s->cString[i + 2] & 0x40) {
s->cString[i] ^= s->cString[i + 2];
s->cString[i + 2] ^= s->cString[i];
s->cString[i] ^= s->cString[i + 2];
i += 2;
continue;
}
/* Third next byte must not be ASCII */
if OF_UNLIKELY (s->cStringLength < i + 3 ||
!(s->cString[i + 3] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Third next byte is the start byte */
if OF_LIKELY (s->cString[i + 3] & 0x40) {
s->cString[i] ^= s->cString[i + 3];
s->cString[i + 3] ^= s->cString[i];
s->cString[i] ^= s->cString[i + 3];
s->cString[i + 1] ^= s->cString[i + 2];
s->cString[i + 2] ^= s->cString[i + 1];
s->cString[i + 1] ^= s->cString[i + 2];
i += 3;
continue;
}
/* UTF-8 does not allow more than 4 bytes per character */
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
- (void)insertString: (OFString*)string
atIndex: (size_t)index
{
size_t newCStringLength;
if (index > s->length)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
if (s->isUTF8)
index = of_string_utf8_get_position(s->cString, index,
s->cStringLength);
newCStringLength = s->cStringLength + [string UTF8StringLength];
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: newCStringLength + 1];
memmove(s->cString + index + [string UTF8StringLength],
s->cString + index, s->cStringLength - index);
memcpy(s->cString + index, [string UTF8String],
[string UTF8StringLength]);
s->cString[newCStringLength] = '\0';
s->cStringLength = newCStringLength;
s->length += [string length];
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]]) {
if (((OFString_UTF8*)string)->s->isUTF8)
s->isUTF8 = YES;
} else
s->isUTF8 = YES;
}
- (void)deleteCharactersInRange: (of_range_t)range
{
size_t start = range.location;
size_t end = range.location + range.length;
if (range.length > SIZE_MAX - range.location || end > s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (s->isUTF8) {
start = of_string_utf8_get_position(s->cString, start,
s->cStringLength);
end = of_string_utf8_get_position(s->cString, end,
s->cStringLength);
}
memmove(s->cString + start, s->cString + end, s->cStringLength - end);
s->hashed = NO;
s->length -= range.length;
s->cStringLength -= end - start;
s->cString[s->cStringLength] = 0;
@try {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)replaceCharactersInRange: (of_range_t)range
withString: (OFString*)replacement
{
size_t start = range.location;
size_t end = range.location + range.length;
size_t newCStringLength, newLength;
if (range.length > SIZE_MAX - range.location || end > s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
newLength = s->length - range.length + [replacement length];
if (s->isUTF8) {
start = of_string_utf8_get_position(s->cString, start,
s->cStringLength);
end = of_string_utf8_get_position(s->cString, end,
s->cStringLength);
}
newCStringLength = s->cStringLength - (end - start) +
[replacement UTF8StringLength];
s->hashed = NO;
s->cString = [self resizeMemory: s->cString
size: newCStringLength + 1];
memmove(s->cString + start + [replacement UTF8StringLength],
s->cString + end, s->cStringLength - end);
memcpy(s->cString + start, [replacement UTF8String],
[replacement UTF8StringLength]);
s->cString[newCStringLength] = '\0';
s->cStringLength = newCStringLength;
s->length = newLength;
}
- (void)replaceOccurrencesOfString: (OFString*)string
withString: (OFString*)replacement
options: (int)options
range: (of_range_t)range
{
const char *searchString = [string UTF8String];
const char *replacementString = [replacement UTF8String];
size_t searchLength = [string UTF8StringLength];
size_t replacementLength = [replacement UTF8StringLength];
size_t i, last, newCStringLength, newLength;
char *newCString;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > [self length])
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (s->isUTF8) {
range.location = of_string_utf8_get_position(s->cString,
range.location, s->cStringLength);
range.length = of_string_utf8_get_position(
s->cString + range.location, range.length,
s->cStringLength - range.location);
}
if ([string UTF8StringLength] > range.length)
return;
newCString = NULL;
newCStringLength = 0;
newLength = s->length;
last = 0;
for (i = range.location; i <= range.length - searchLength; i++) {
if (memcmp(s->cString + i, searchString, searchLength))
continue;
@try {
newCString = [self
resizeMemory: newCString
size: newCStringLength + i - last +
replacementLength + 1];
} @catch (id e) {
[self freeMemory: newCString];
@throw e;
}
memcpy(newCString + newCStringLength, s->cString + last,
i - last);
memcpy(newCString + newCStringLength + i - last,
replacementString, replacementLength);
newCStringLength += i - last + replacementLength;
newLength = newLength - [string length] + [replacement length];
i += searchLength - 1;
last = i + 1;
}
@try {
newCString = [self resizeMemory: newCString
size: newCStringLength +
s->cStringLength - last + 1];
} @catch (id e) {
[self freeMemory: newCString];
@throw e;
}
memcpy(newCString + newCStringLength, s->cString + last,
s->cStringLength - last);
newCStringLength += s->cStringLength - last;
newCString[newCStringLength] = 0;
[self freeMemory: s->cString];
s->hashed = NO;
s->cString = newCString;
s->cStringLength = newCStringLength;
s->length = newLength;
}
- (void)deleteLeadingWhitespaces
{
size_t i;
for (i = 0; i < s->cStringLength; i++)
if (s->cString[i] != ' ' && s->cString[i] != '\t' &&
s->cString[i] != '\n' && s->cString[i] != '\r' &&
s->cString[i] != '\f')
break;
s->hashed = NO;
s->cStringLength -= i;
s->length -= i;
memmove(s->cString, s->cString + i, s->cStringLength);
s->cString[s->cStringLength] = '\0';
@try {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)deleteTrailingWhitespaces
{
size_t d;
char *p;
s->hashed = NO;
d = 0;
for (p = s->cString + s->cStringLength - 1; p >= s->cString; p--) {
if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
*p != '\f')
break;
*p = '\0';
d++;
}
s->cStringLength -= d;
s->length -= d;
@try {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)deleteEnclosingWhitespaces
{
size_t d, i;
char *p;
s->hashed = NO;
d = 0;
for (p = s->cString + s->cStringLength - 1; p >= s->cString; p--) {
if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
*p != '\f')
break;
*p = '\0';
d++;
}
s->cStringLength -= d;
s->length -= d;
for (i = 0; i < s->cStringLength; i++)
if (s->cString[i] != ' ' && s->cString[i] != '\t' &&
s->cString[i] != '\n' && s->cString[i] != '\r' &&
s->cString[i] != '\f')
break;
s->cStringLength -= i;
s->length -= i;
memmove(s->cString, s->cString + i, s->cStringLength);
s->cString[s->cStringLength] = '\0';
@try {
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)makeImmutable
{
object_setClass(self, [OFString_UTF8 class]);
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
|
}
}
- (void)reverse
{
size_t i, j;
_s->hashed = NO;
/* We reverse all bytes and restore UTF-8 later, if necessary */
for (i = 0, j = _s->cStringLength - 1; i < _s->cStringLength / 2;
i++, j--) {
_s->cString[i] ^= _s->cString[j];
_s->cString[j] ^= _s->cString[i];
_s->cString[i] ^= _s->cString[j];
}
if (!_s->isUTF8)
return;
for (i = 0; i < _s->cStringLength; i++) {
/* ASCII */
if OF_LIKELY (!(_s->cString[i] & 0x80))
continue;
/* A start byte can't happen first as we reversed everything */
if OF_UNLIKELY (_s->cString[i] & 0x40)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Next byte must not be ASCII */
if OF_UNLIKELY (_s->cStringLength < i + 1 ||
!(_s->cString[i + 1] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Next byte is the start byte */
if OF_LIKELY (_s->cString[i + 1] & 0x40) {
_s->cString[i] ^= _s->cString[i + 1];
_s->cString[i + 1] ^= _s->cString[i];
_s->cString[i] ^= _s->cString[i + 1];
i++;
continue;
}
/* Second next byte must not be ASCII */
if OF_UNLIKELY (_s->cStringLength < i + 2 ||
!(_s->cString[i + 2] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Second next byte is the start byte */
if OF_LIKELY (_s->cString[i + 2] & 0x40) {
_s->cString[i] ^= _s->cString[i + 2];
_s->cString[i + 2] ^= _s->cString[i];
_s->cString[i] ^= _s->cString[i + 2];
i += 2;
continue;
}
/* Third next byte must not be ASCII */
if OF_UNLIKELY (_s->cStringLength < i + 3 ||
!(_s->cString[i + 3] & 0x80))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* Third next byte is the start byte */
if OF_LIKELY (_s->cString[i + 3] & 0x40) {
_s->cString[i] ^= _s->cString[i + 3];
_s->cString[i + 3] ^= _s->cString[i];
_s->cString[i] ^= _s->cString[i + 3];
_s->cString[i + 1] ^= _s->cString[i + 2];
_s->cString[i + 2] ^= _s->cString[i + 1];
_s->cString[i + 1] ^= _s->cString[i + 2];
i += 3;
continue;
}
/* UTF-8 does not allow more than 4 bytes per character */
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
- (void)insertString: (OFString*)string
atIndex: (size_t)index
{
size_t newCStringLength;
if (index > _s->length)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
if (_s->isUTF8)
index = of_string_utf8_get_position(_s->cString, index,
_s->cStringLength);
newCStringLength = _s->cStringLength + [string UTF8StringLength];
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: newCStringLength + 1];
memmove(_s->cString + index + [string UTF8StringLength],
_s->cString + index, _s->cStringLength - index);
memcpy(_s->cString + index, [string UTF8String],
[string UTF8StringLength]);
_s->cString[newCStringLength] = '\0';
_s->cStringLength = newCStringLength;
_s->length += [string length];
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]]) {
if (((OFString_UTF8*)string)->_s->isUTF8)
_s->isUTF8 = YES;
} else
_s->isUTF8 = YES;
}
- (void)deleteCharactersInRange: (of_range_t)range
{
size_t start = range.location;
size_t end = range.location + range.length;
if (range.length > SIZE_MAX - range.location || end > _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (_s->isUTF8) {
start = of_string_utf8_get_position(_s->cString, start,
_s->cStringLength);
end = of_string_utf8_get_position(_s->cString, end,
_s->cStringLength);
}
memmove(_s->cString + start, _s->cString + end,
_s->cStringLength - end);
_s->hashed = NO;
_s->length -= range.length;
_s->cStringLength -= end - start;
_s->cString[_s->cStringLength] = 0;
@try {
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)replaceCharactersInRange: (of_range_t)range
withString: (OFString*)replacement
{
size_t start = range.location;
size_t end = range.location + range.length;
size_t newCStringLength, newLength;
if (range.length > SIZE_MAX - range.location || end > _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
newLength = _s->length - range.length + [replacement length];
if (_s->isUTF8) {
start = of_string_utf8_get_position(_s->cString, start,
_s->cStringLength);
end = of_string_utf8_get_position(_s->cString, end,
_s->cStringLength);
}
newCStringLength = _s->cStringLength - (end - start) +
[replacement UTF8StringLength];
_s->hashed = NO;
_s->cString = [self resizeMemory: _s->cString
size: newCStringLength + 1];
memmove(_s->cString + start + [replacement UTF8StringLength],
_s->cString + end, _s->cStringLength - end);
memcpy(_s->cString + start, [replacement UTF8String],
[replacement UTF8StringLength]);
_s->cString[newCStringLength] = '\0';
_s->cStringLength = newCStringLength;
_s->length = newLength;
}
- (void)replaceOccurrencesOfString: (OFString*)string
withString: (OFString*)replacement
options: (int)options
range: (of_range_t)range
{
const char *searchString = [string UTF8String];
const char *replacementString = [replacement UTF8String];
size_t searchLength = [string UTF8StringLength];
size_t replacementLength = [replacement UTF8StringLength];
size_t i, last, newCStringLength, newLength;
char *newCString;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > [self length])
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (_s->isUTF8) {
range.location = of_string_utf8_get_position(_s->cString,
range.location, _s->cStringLength);
range.length = of_string_utf8_get_position(
_s->cString + range.location, range.length,
_s->cStringLength - range.location);
}
if ([string UTF8StringLength] > range.length)
return;
newCString = NULL;
newCStringLength = 0;
newLength = _s->length;
last = 0;
for (i = range.location; i <= range.length - searchLength; i++) {
if (memcmp(_s->cString + i, searchString, searchLength))
continue;
@try {
newCString = [self
resizeMemory: newCString
size: newCStringLength + i - last +
replacementLength + 1];
} @catch (id e) {
[self freeMemory: newCString];
@throw e;
}
memcpy(newCString + newCStringLength, _s->cString + last,
i - last);
memcpy(newCString + newCStringLength + i - last,
replacementString, replacementLength);
newCStringLength += i - last + replacementLength;
newLength = newLength - [string length] + [replacement length];
i += searchLength - 1;
last = i + 1;
}
@try {
newCString = [self resizeMemory: newCString
size: newCStringLength +
_s->cStringLength - last + 1];
} @catch (id e) {
[self freeMemory: newCString];
@throw e;
}
memcpy(newCString + newCStringLength, _s->cString + last,
_s->cStringLength - last);
newCStringLength += _s->cStringLength - last;
newCString[newCStringLength] = 0;
[self freeMemory: _s->cString];
_s->hashed = NO;
_s->cString = newCString;
_s->cStringLength = newCStringLength;
_s->length = newLength;
}
- (void)deleteLeadingWhitespaces
{
size_t i;
for (i = 0; i < _s->cStringLength; i++)
if (_s->cString[i] != ' ' && _s->cString[i] != '\t' &&
_s->cString[i] != '\n' && _s->cString[i] != '\r' &&
_s->cString[i] != '\f')
break;
_s->hashed = NO;
_s->cStringLength -= i;
_s->length -= i;
memmove(_s->cString, _s->cString + i, _s->cStringLength);
_s->cString[_s->cStringLength] = '\0';
@try {
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)deleteTrailingWhitespaces
{
size_t d;
char *p;
_s->hashed = NO;
d = 0;
for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) {
if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
*p != '\f')
break;
*p = '\0';
d++;
}
_s->cStringLength -= d;
_s->length -= d;
@try {
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)deleteEnclosingWhitespaces
{
size_t d, i;
char *p;
_s->hashed = NO;
d = 0;
for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) {
if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r' &&
*p != '\f')
break;
*p = '\0';
d++;
}
_s->cStringLength -= d;
_s->length -= d;
for (i = 0; i < _s->cStringLength; i++)
if (_s->cString[i] != ' ' && _s->cString[i] != '\t' &&
_s->cString[i] != '\n' && _s->cString[i] != '\r' &&
_s->cString[i] != '\f')
break;
_s->cStringLength -= i;
_s->length -= i;
memmove(_s->cString, _s->cString + i, _s->cStringLength);
_s->cString[_s->cStringLength] = '\0';
@try {
_s->cString = [self resizeMemory: _s->cString
size: _s->cStringLength + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't really care, as we only made it smaller */
}
}
- (void)makeImmutable
{
object_setClass(self, [OFString_UTF8 class]);
}
@end
|
Modified src/OFMutex.h
from [241248bc92]
to [4850473658].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#import "threading.h"
/*!
* @brief A class for creating mutual exclusions.
*/
@interface OFMutex: OFObject <OFLocking>
{
of_mutex_t mutex;
BOOL initialized;
OFString *name;
}
/*!
* @brief Creates a new mutex.
*
* @return A new autoreleased mutex.
*/
+ (instancetype)mutex;
@end
|
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#import "threading.h"
/*!
* @brief A class for creating mutual exclusions.
*/
@interface OFMutex: OFObject <OFLocking>
{
of_mutex_t _mutex;
BOOL _initialized;
OFString *_name;
}
/*!
* @brief Creates a new mutex.
*
* @return A new autoreleased mutex.
*/
+ (instancetype)mutex;
@end
|
Modified src/OFMutex.m
from [03afd45a89]
to [d5036265a2].
︙ | | | ︙ | |
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_mutex_new(&mutex)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
initialized = YES;
return self;
}
- (void)lock
{
if (!of_mutex_lock(&mutex))
@throw [OFLockFailedException exceptionWithClass: [self class]
lock: self];
}
- (BOOL)tryLock
{
return of_mutex_trylock(&mutex);
}
- (void)unlock
{
if (!of_mutex_unlock(&mutex))
@throw [OFUnlockFailedException exceptionWithClass: [self class]
lock: self];
}
- (void)setName: (OFString*)name_
{
OF_SETTER(name, name_, YES, 1)
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (OFString*)description
{
if (name == nil)
return [super description];
return [OFString stringWithFormat: @"<%@: %@>", [self className], name];
}
- (void)dealloc
{
if (initialized)
if (!of_mutex_free(&mutex))
@throw [OFStillLockedException
exceptionWithClass: [self class]
lock: self];
[name release];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_mutex_new(&_mutex)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = YES;
return self;
}
- (void)lock
{
if (!of_mutex_lock(&_mutex))
@throw [OFLockFailedException exceptionWithClass: [self class]
lock: self];
}
- (BOOL)tryLock
{
return of_mutex_trylock(&_mutex);
}
- (void)unlock
{
if (!of_mutex_unlock(&_mutex))
@throw [OFUnlockFailedException exceptionWithClass: [self class]
lock: self];
}
- (void)setName: (OFString*)name
{
OF_SETTER(_name, name, YES, 1)
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (OFString*)description
{
if (_name == nil)
return [super description];
return [OFString stringWithFormat: @"<%@: %@>",
[self className], _name];
}
- (void)dealloc
{
if (_initialized)
if (!of_mutex_free(&_mutex))
@throw [OFStillLockedException
exceptionWithClass: [self class]
lock: self];
[_name release];
[super dealloc];
}
@end
|
Modified src/OFNumber.h
from [c711cafca0]
to [b3a58136c1].
︙ | | | ︙ | |
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
* @brief Provides a way to store a number in an object.
*/
@interface OFNumber: OFObject <OFCopying, OFComparing, OFSerialization,
OFJSONRepresentation>
{
union of_number_value {
BOOL bool_;
signed char char_;
signed short short_;
signed int int_;
signed long long_;
unsigned char uchar;
unsigned short ushort;
unsigned int uint;
unsigned long ulong;
int8_t int8;
int16_t int16;
int32_t int32;
|
|
|
|
|
|
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
* @brief Provides a way to store a number in an object.
*/
@interface OFNumber: OFObject <OFCopying, OFComparing, OFSerialization,
OFJSONRepresentation>
{
union of_number_value {
BOOL bool_;
signed char schar;
signed short sshort;
signed int sint;
signed long slong;
unsigned char uchar;
unsigned short ushort;
unsigned int uint;
unsigned long ulong;
int8_t int8;
int16_t int16;
int32_t int32;
|
︙ | | | ︙ | |
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
intmax_t intmax;
uintmax_t uintmax;
ptrdiff_t ptrdiff;
intptr_t intptr;
uintptr_t uintptr;
float float_;
double double_;
} value;
of_number_type_t type;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_number_type_t type;
#endif
/*!
* @brief Creates a new OFNumber with the specified BOOL.
*
* @param bool_ A BOOL which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithBool: (BOOL)bool_;
/*!
* @brief Creates a new OFNumber with the specified signed char.
*
* @param char_ A signed char which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithChar: (signed char)char_;
/*!
* @brief Creates a new OFNumber with the specified signed short.
*
* @param short_ A signed short which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithShort: (signed short)short_;
/*!
* @brief Creates a new OFNumber with the specified signed int.
*
* @param int_ A signed int which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithInt: (signed int)int_;
/*!
* @brief Creates a new OFNumber with the specified signed long.
*
* @param long_ A signed long which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithLong: (signed long)long_;
/*!
* @brief Creates a new OFNumber with the specified unsigned char.
*
* @param uchar An unsigned char which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
|
|
|
|
|
|
|
|
|
|
|
|
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
intmax_t intmax;
uintmax_t uintmax;
ptrdiff_t ptrdiff;
intptr_t intptr;
uintptr_t uintptr;
float float_;
double double_;
} _value;
of_number_type_t _type;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) of_number_type_t type;
#endif
/*!
* @brief Creates a new OFNumber with the specified BOOL.
*
* @param bool_ A BOOL which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithBool: (BOOL)bool_;
/*!
* @brief Creates a new OFNumber with the specified signed char.
*
* @param schar A signed char which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithChar: (signed char)schar;
/*!
* @brief Creates a new OFNumber with the specified signed short.
*
* @param sshort A signed short which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithShort: (signed short)sshort;
/*!
* @brief Creates a new OFNumber with the specified signed int.
*
* @param sint A signed int which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithInt: (signed int)sint;
/*!
* @brief Creates a new OFNumber with the specified signed long.
*
* @param slong A signed long which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
+ (instancetype)numberWithLong: (signed long)slong;
/*!
* @brief Creates a new OFNumber with the specified unsigned char.
*
* @param uchar An unsigned char which the OFNumber should contain
* @return A new autoreleased OFNumber
*/
|
︙ | | | ︙ | |
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
|
*/
- initWithBool: (BOOL)bool_;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* char.
*
* @param char_ A signed char which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithChar: (signed char)char_;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* short.
*
* @param short_ A signed short which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithShort: (signed short)short_;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* int.
*
* @param int_ A signed int which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithInt: (signed int)int_;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* long.
*
* @param long_ A signed long which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithLong: (signed long)long_;
/*!
* @brief Initializes an already allocated OFNumber with the specified unsigned
* char.
*
* @param uchar An unsigned char which the OFNumber should contain
* @return An initialized OFNumber
|
|
|
|
|
|
|
|
|
|
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
|
*/
- initWithBool: (BOOL)bool_;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* char.
*
* @param schar A signed char which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithChar: (signed char)schar;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* short.
*
* @param sshort A signed short which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithShort: (signed short)sshort;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* int.
*
* @param sint A signed int which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithInt: (signed int)sint;
/*!
* @brief Initializes an already allocated OFNumber with the specified signed
* long.
*
* @param slong A signed long which the OFNumber should contain
* @return An initialized OFNumber
*/
- initWithLong: (signed long)slong;
/*!
* @brief Initializes an already allocated OFNumber with the specified unsigned
* char.
*
* @param uchar An unsigned char which the OFNumber should contain
* @return An initialized OFNumber
|
︙ | | | ︙ | |
Modified src/OFNumber.m
from [ae195c0c97]
to [df1e685381].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "autorelease.h"
#import "macros.h"
#define RETURN_AS(t) \
switch (type) { \
case OF_NUMBER_BOOL: \
return (t)value.bool_; \
case OF_NUMBER_CHAR: \
return (t)value.char_; \
case OF_NUMBER_SHORT: \
return (t)value.short_; \
case OF_NUMBER_INT: \
return (t)value.int_; \
case OF_NUMBER_LONG: \
return (t)value.long_; \
case OF_NUMBER_UCHAR: \
return (t)value.uchar; \
case OF_NUMBER_USHORT: \
return (t)value.ushort; \
case OF_NUMBER_UINT: \
return (t)value.uint; \
case OF_NUMBER_ULONG: \
return (t)value.ulong; \
case OF_NUMBER_INT8: \
return (t)value.int8; \
case OF_NUMBER_INT16: \
return (t)value.int16; \
case OF_NUMBER_INT32: \
return (t)value.int32; \
case OF_NUMBER_INT64: \
return (t)value.int64; \
case OF_NUMBER_UINT8: \
return (t)value.uint8; \
case OF_NUMBER_UINT16: \
return (t)value.uint16; \
case OF_NUMBER_UINT32: \
return (t)value.uint32; \
case OF_NUMBER_UINT64: \
return (t)value.uint64; \
case OF_NUMBER_SIZE: \
return (t)value.size; \
case OF_NUMBER_SSIZE: \
return (t)value.ssize; \
case OF_NUMBER_INTMAX: \
return (t)value.intmax; \
case OF_NUMBER_UINTMAX: \
return (t)value.uintmax; \
case OF_NUMBER_PTRDIFF: \
return (t)value.ptrdiff; \
case OF_NUMBER_INTPTR: \
return (t)value.intptr; \
case OF_NUMBER_UINTPTR: \
return (t)value.uintptr; \
case OF_NUMBER_FLOAT: \
return (t)value.float_; \
case OF_NUMBER_DOUBLE: \
return (t)value.double_; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE(o, n) \
switch (type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: \
value.bool_ o [n boolValue]]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: \
value.char_ o [n charValue]]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: \
value.short_ o [n shortValue]]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: \
value.int_ o [n intValue]]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: \
value.long_ o [n longValue]]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
value.uchar o [n unsignedCharValue]]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
value.ushort o [n unsignedShortValue]]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: \
value.uint o [n unsignedIntValue]]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
value.ulong o [n unsignedLongValue]]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: \
value.int8 o [n int8Value]]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: \
value.int16 o [n int16Value]]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: \
value.int32 o [n int32Value]]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: \
value.int64 o [n int64Value]]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: \
value.uint8 o [n uInt8Value]]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: \
value.uint16 o [n uInt16Value]]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: \
value.uint32 o [n uInt32Value]]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: \
value.uint64 o [n uInt64Value]]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: \
value.size o [n sizeValue]]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: \
value.ssize o [n sSizeValue]]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: \
value.intmax o [n intMaxValue]]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: \
value.uintmax o [n uIntMaxValue]]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: \
value.ptrdiff o [n ptrDiffValue]]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: \
value.intptr o [n intPtrValue]]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: \
value.uintptr o [n uIntPtrValue]]; \
case OF_NUMBER_FLOAT: \
return [OFNumber numberWithFloat: \
value.float_ o [n floatValue]]; \
case OF_NUMBER_DOUBLE: \
return [OFNumber numberWithDouble: \
value.double_ o [n doubleValue]]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE2(o, n) \
switch (type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: \
value.bool_ o [n boolValue]]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: \
value.char_ o [n charValue]]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: \
value.short_ o [n shortValue]]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: \
value.int_ o [n intValue]]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: \
value.long_ o [n longValue]]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
value.uchar o [n unsignedCharValue]]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
value.ushort o [n unsignedShortValue]]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: \
value.uint o [n unsignedIntValue]]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
value.ulong o [n unsignedLongValue]]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: \
value.int8 o [n int8Value]]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: \
value.int16 o [n int16Value]]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: \
value.int32 o [n int32Value]]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: \
value.int64 o [n int64Value]]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: \
value.uint8 o [n uInt8Value]]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: \
value.uint16 o [n uInt16Value]]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: \
value.uint32 o [n uInt32Value]]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: \
value.uint64 o [n uInt64Value]]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: \
value.size o [n sizeValue]]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: \
value.ssize o [n sSizeValue]]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: \
value.intmax o [n intMaxValue]]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: \
value.uintmax o [n uIntMaxValue]]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: \
value.ptrdiff o [n ptrDiffValue]]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: \
value.intptr o [n intPtrValue]]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: \
value.uintptr o [n uIntPtrValue]]; \
case OF_NUMBER_FLOAT: \
case OF_NUMBER_DOUBLE: \
@throw [OFInvalidArgumentException \
exceptionWithClass: [self class] \
selector: _cmd]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE3(o) \
switch (type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: value.bool_ o]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: value.char_ o]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: value.short_ o]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: value.int_ o]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: value.long_ o]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
value.uchar o]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
value.ushort o]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: value.uint o]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
value.ulong o]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: value.int8 o]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: value.int16 o]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: value.int32 o]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: value.int64 o]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: value.uint8 o]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: value.uint16 o]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: value.uint32 o]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: value.uint64 o]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: value.size o]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: value.ssize o]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: value.intmax o]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: value.uintmax o]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: value.ptrdiff o]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: value.intptr o]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: value.uintptr o]; \
case OF_NUMBER_FLOAT: \
return [OFNumber numberWithFloat: value.float_ o]; \
case OF_NUMBER_DOUBLE: \
return [OFNumber numberWithDouble: value.double_ o]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
@implementation OFNumber
+ (instancetype)numberWithBool: (BOOL)bool_
{
return [[[self alloc] initWithBool: bool_] autorelease];
}
+ (instancetype)numberWithChar: (signed char)char_
{
return [[[self alloc] initWithChar: char_] autorelease];
}
+ (instancetype)numberWithShort: (signed short)short_
{
return [[[self alloc] initWithShort: short_] autorelease];
}
+ (instancetype)numberWithInt: (signed int)int_
{
return [[[self alloc] initWithInt: int_] autorelease];
}
+ (instancetype)numberWithLong: (signed long)long_
{
return [[[self alloc] initWithLong: long_] autorelease];
}
+ (instancetype)numberWithUnsignedChar: (unsigned char)uchar
{
return [[[self alloc] initWithUnsignedChar: uchar] autorelease];
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "autorelease.h"
#import "macros.h"
#define RETURN_AS(t) \
switch (_type) { \
case OF_NUMBER_BOOL: \
return (t)_value.bool_; \
case OF_NUMBER_CHAR: \
return (t)_value.schar; \
case OF_NUMBER_SHORT: \
return (t)_value.sshort; \
case OF_NUMBER_INT: \
return (t)_value.sint; \
case OF_NUMBER_LONG: \
return (t)_value.slong; \
case OF_NUMBER_UCHAR: \
return (t)_value.uchar; \
case OF_NUMBER_USHORT: \
return (t)_value.ushort; \
case OF_NUMBER_UINT: \
return (t)_value.uint; \
case OF_NUMBER_ULONG: \
return (t)_value.ulong; \
case OF_NUMBER_INT8: \
return (t)_value.int8; \
case OF_NUMBER_INT16: \
return (t)_value.int16; \
case OF_NUMBER_INT32: \
return (t)_value.int32; \
case OF_NUMBER_INT64: \
return (t)_value.int64; \
case OF_NUMBER_UINT8: \
return (t)_value.uint8; \
case OF_NUMBER_UINT16: \
return (t)_value.uint16; \
case OF_NUMBER_UINT32: \
return (t)_value.uint32; \
case OF_NUMBER_UINT64: \
return (t)_value.uint64; \
case OF_NUMBER_SIZE: \
return (t)_value.size; \
case OF_NUMBER_SSIZE: \
return (t)_value.ssize; \
case OF_NUMBER_INTMAX: \
return (t)_value.intmax; \
case OF_NUMBER_UINTMAX: \
return (t)_value.uintmax; \
case OF_NUMBER_PTRDIFF: \
return (t)_value.ptrdiff; \
case OF_NUMBER_INTPTR: \
return (t)_value.intptr; \
case OF_NUMBER_UINTPTR: \
return (t)_value.uintptr; \
case OF_NUMBER_FLOAT: \
return (t)_value.float_; \
case OF_NUMBER_DOUBLE: \
return (t)_value.double_; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE(o, n) \
switch (_type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: \
_value.bool_ o [n boolValue]]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: \
_value.schar o [n charValue]]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: \
_value.sshort o [n shortValue]]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: \
_value.sint o [n intValue]]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: \
_value.slong o [n longValue]]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
_value.uchar o [n unsignedCharValue]]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
_value.ushort o [n unsignedShortValue]]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: \
_value.uint o [n unsignedIntValue]]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
_value.ulong o [n unsignedLongValue]]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: \
_value.int8 o [n int8Value]]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: \
_value.int16 o [n int16Value]]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: \
_value.int32 o [n int32Value]]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: \
_value.int64 o [n int64Value]]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: \
_value.uint8 o [n uInt8Value]]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: \
_value.uint16 o [n uInt16Value]]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: \
_value.uint32 o [n uInt32Value]]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: \
_value.uint64 o [n uInt64Value]]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: \
_value.size o [n sizeValue]]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: \
_value.ssize o [n sSizeValue]]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: \
_value.intmax o [n intMaxValue]]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: \
_value.uintmax o [n uIntMaxValue]]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: \
_value.ptrdiff o [n ptrDiffValue]]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: \
_value.intptr o [n intPtrValue]]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: \
_value.uintptr o [n uIntPtrValue]]; \
case OF_NUMBER_FLOAT: \
return [OFNumber numberWithFloat: \
_value.float_ o [n floatValue]]; \
case OF_NUMBER_DOUBLE: \
return [OFNumber numberWithDouble: \
_value.double_ o [n doubleValue]]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE2(o, n) \
switch (_type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: \
_value.bool_ o [n boolValue]]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: \
_value.schar o [n charValue]]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: \
_value.sshort o [n shortValue]]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: \
_value.sint o [n intValue]]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: \
_value.slong o [n longValue]]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
_value.uchar o [n unsignedCharValue]]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
_value.ushort o [n unsignedShortValue]]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: \
_value.uint o [n unsignedIntValue]]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
_value.ulong o [n unsignedLongValue]]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: \
_value.int8 o [n int8Value]]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: \
_value.int16 o [n int16Value]]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: \
_value.int32 o [n int32Value]]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: \
_value.int64 o [n int64Value]]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: \
_value.uint8 o [n uInt8Value]]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: \
_value.uint16 o [n uInt16Value]]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: \
_value.uint32 o [n uInt32Value]]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: \
_value.uint64 o [n uInt64Value]]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: \
_value.size o [n sizeValue]]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: \
_value.ssize o [n sSizeValue]]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: \
_value.intmax o [n intMaxValue]]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: \
_value.uintmax o [n uIntMaxValue]]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: \
_value.ptrdiff o [n ptrDiffValue]]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: \
_value.intptr o [n intPtrValue]]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: \
_value.uintptr o [n uIntPtrValue]]; \
case OF_NUMBER_FLOAT: \
case OF_NUMBER_DOUBLE: \
@throw [OFInvalidArgumentException \
exceptionWithClass: [self class] \
selector: _cmd]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
#define CALCULATE3(o) \
switch (_type) { \
case OF_NUMBER_BOOL: \
return [OFNumber numberWithBool: _value.bool_ o]; \
case OF_NUMBER_CHAR: \
return [OFNumber numberWithChar: _value.schar o]; \
case OF_NUMBER_SHORT: \
return [OFNumber numberWithShort: _value.sshort o]; \
case OF_NUMBER_INT: \
return [OFNumber numberWithInt: _value.sint o]; \
case OF_NUMBER_LONG: \
return [OFNumber numberWithLong: _value.slong o]; \
case OF_NUMBER_UCHAR: \
return [OFNumber numberWithUnsignedChar: \
_value.uchar o]; \
case OF_NUMBER_USHORT: \
return [OFNumber numberWithUnsignedShort: \
_value.ushort o]; \
case OF_NUMBER_UINT: \
return [OFNumber numberWithUnsignedInt: _value.uint o]; \
case OF_NUMBER_ULONG: \
return [OFNumber numberWithUnsignedLong: \
_value.ulong o]; \
case OF_NUMBER_INT8: \
return [OFNumber numberWithInt8: _value.int8 o]; \
case OF_NUMBER_INT16: \
return [OFNumber numberWithInt16: _value.int16 o]; \
case OF_NUMBER_INT32: \
return [OFNumber numberWithInt32: _value.int32 o]; \
case OF_NUMBER_INT64: \
return [OFNumber numberWithInt64: _value.int64 o]; \
case OF_NUMBER_UINT8: \
return [OFNumber numberWithUInt8: _value.uint8 o]; \
case OF_NUMBER_UINT16: \
return [OFNumber numberWithUInt16: _value.uint16 o]; \
case OF_NUMBER_UINT32: \
return [OFNumber numberWithUInt32: _value.uint32 o]; \
case OF_NUMBER_UINT64: \
return [OFNumber numberWithUInt64: _value.uint64 o]; \
case OF_NUMBER_SIZE: \
return [OFNumber numberWithSize: _value.size o]; \
case OF_NUMBER_SSIZE: \
return [OFNumber numberWithSSize: _value.ssize o]; \
case OF_NUMBER_INTMAX: \
return [OFNumber numberWithIntMax: _value.intmax o]; \
case OF_NUMBER_UINTMAX: \
return [OFNumber numberWithUIntMax: _value.uintmax o]; \
case OF_NUMBER_PTRDIFF: \
return [OFNumber numberWithPtrDiff: _value.ptrdiff o]; \
case OF_NUMBER_INTPTR: \
return [OFNumber numberWithIntPtr: _value.intptr o]; \
case OF_NUMBER_UINTPTR: \
return [OFNumber numberWithUIntPtr: _value.uintptr o]; \
case OF_NUMBER_FLOAT: \
return [OFNumber numberWithFloat: _value.float_ o]; \
case OF_NUMBER_DOUBLE: \
return [OFNumber numberWithDouble: _value.double_ o]; \
default: \
@throw [OFInvalidFormatException \
exceptionWithClass: [self class]]; \
}
@implementation OFNumber
+ (instancetype)numberWithBool: (BOOL)bool_
{
return [[[self alloc] initWithBool: bool_] autorelease];
}
+ (instancetype)numberWithChar: (signed char)schar
{
return [[[self alloc] initWithChar: schar] autorelease];
}
+ (instancetype)numberWithShort: (signed short)sshort
{
return [[[self alloc] initWithShort: sshort] autorelease];
}
+ (instancetype)numberWithInt: (signed int)sint
{
return [[[self alloc] initWithInt: sint] autorelease];
}
+ (instancetype)numberWithLong: (signed long)slong
{
return [[[self alloc] initWithLong: slong] autorelease];
}
+ (instancetype)numberWithUnsignedChar: (unsigned char)uchar
{
return [[[self alloc] initWithUnsignedChar: uchar] autorelease];
}
|
︙ | | | ︙ | |
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
|
abort();
}
- initWithBool: (BOOL)bool_
{
self = [super init];
value.bool_ = (bool_ ? YES : NO);
type = OF_NUMBER_BOOL;
return self;
}
- initWithChar: (signed char)char_
{
self = [super init];
value.char_ = char_;
type = OF_NUMBER_CHAR;
return self;
}
- initWithShort: (signed short)short_
{
self = [super init];
value.short_ = short_;
type = OF_NUMBER_SHORT;
return self;
}
- initWithInt: (signed int)int_
{
self = [super init];
value.int_ = int_;
type = OF_NUMBER_INT;
return self;
}
- initWithLong: (signed long)long_
{
self = [super init];
value.long_ = long_;
type = OF_NUMBER_LONG;
return self;
}
- initWithUnsignedChar: (unsigned char)uchar
{
self = [super init];
value.uchar = uchar;
type = OF_NUMBER_UCHAR;
return self;
}
- initWithUnsignedShort: (unsigned short)ushort
{
self = [super init];
value.ushort = ushort;
type = OF_NUMBER_USHORT;
return self;
}
- initWithUnsignedInt: (unsigned int)uint
{
self = [super init];
value.uint = uint;
type = OF_NUMBER_UINT;
return self;
}
- initWithUnsignedLong: (unsigned long)ulong
{
self = [super init];
value.ulong = ulong;
type = OF_NUMBER_ULONG;
return self;
}
- initWithInt8: (int8_t)int8
{
self = [super init];
value.int8 = int8;
type = OF_NUMBER_INT8;
return self;
}
- initWithInt16: (int16_t)int16
{
self = [super init];
value.int16 = int16;
type = OF_NUMBER_INT16;
return self;
}
- initWithInt32: (int32_t)int32
{
self = [super init];
value.int32 = int32;
type = OF_NUMBER_INT32;
return self;
}
- initWithInt64: (int64_t)int64
{
self = [super init];
value.int64 = int64;
type = OF_NUMBER_INT64;
return self;
}
- initWithUInt8: (uint8_t)uint8
{
self = [super init];
value.uint8 = uint8;
type = OF_NUMBER_UINT8;
return self;
}
- initWithUInt16: (uint16_t)uint16
{
self = [super init];
value.uint16 = uint16;
type = OF_NUMBER_UINT16;
return self;
}
- initWithUInt32: (uint32_t)uint32
{
self = [super init];
value.uint32 = uint32;
type = OF_NUMBER_UINT32;
return self;
}
- initWithUInt64: (uint64_t)uint64
{
self = [super init];
value.uint64 = uint64;
type = OF_NUMBER_UINT64;
return self;
}
- initWithSize: (size_t)size
{
self = [super init];
value.size = size;
type = OF_NUMBER_SIZE;
return self;
}
- initWithSSize: (ssize_t)ssize
{
self = [super init];
value.ssize = ssize;
type = OF_NUMBER_SSIZE;
return self;
}
- initWithIntMax: (intmax_t)intmax
{
self = [super init];
value.intmax = intmax;
type = OF_NUMBER_INTMAX;
return self;
}
- initWithUIntMax: (uintmax_t)uintmax
{
self = [super init];
value.uintmax = uintmax;
type = OF_NUMBER_UINTMAX;
return self;
}
- initWithPtrDiff: (ptrdiff_t)ptrdiff
{
self = [super init];
value.ptrdiff = ptrdiff;
type = OF_NUMBER_PTRDIFF;
return self;
}
- initWithIntPtr: (intptr_t)intptr
{
self = [super init];
value.intptr = intptr;
type = OF_NUMBER_INTPTR;
return self;
}
- initWithUIntPtr: (uintptr_t)uintptr
{
self = [super init];
value.uintptr = uintptr;
type = OF_NUMBER_UINTPTR;
return self;
}
- initWithFloat: (float)float_
{
self = [super init];
value.float_ = float_;
type = OF_NUMBER_FLOAT;
return self;
}
- initWithDouble: (double)double_
{
self = [super init];
value.double_ = double_;
type = OF_NUMBER_DOUBLE;
return self;
}
- initWithSerialization: (OFXMLElement*)element
{
self = [super init];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
|
abort();
}
- initWithBool: (BOOL)bool_
{
self = [super init];
_value.bool_ = (bool_ ? YES : NO);
_type = OF_NUMBER_BOOL;
return self;
}
- initWithChar: (signed char)schar
{
self = [super init];
_value.schar = schar;
_type = OF_NUMBER_CHAR;
return self;
}
- initWithShort: (signed short)sshort
{
self = [super init];
_value.sshort = sshort;
_type = OF_NUMBER_SHORT;
return self;
}
- initWithInt: (signed int)sint
{
self = [super init];
_value.sint = sint;
_type = OF_NUMBER_INT;
return self;
}
- initWithLong: (signed long)slong
{
self = [super init];
_value.slong = slong;
_type = OF_NUMBER_LONG;
return self;
}
- initWithUnsignedChar: (unsigned char)uchar
{
self = [super init];
_value.uchar = uchar;
_type = OF_NUMBER_UCHAR;
return self;
}
- initWithUnsignedShort: (unsigned short)ushort
{
self = [super init];
_value.ushort = ushort;
_type = OF_NUMBER_USHORT;
return self;
}
- initWithUnsignedInt: (unsigned int)uint
{
self = [super init];
_value.uint = uint;
_type = OF_NUMBER_UINT;
return self;
}
- initWithUnsignedLong: (unsigned long)ulong
{
self = [super init];
_value.ulong = ulong;
_type = OF_NUMBER_ULONG;
return self;
}
- initWithInt8: (int8_t)int8
{
self = [super init];
_value.int8 = int8;
_type = OF_NUMBER_INT8;
return self;
}
- initWithInt16: (int16_t)int16
{
self = [super init];
_value.int16 = int16;
_type = OF_NUMBER_INT16;
return self;
}
- initWithInt32: (int32_t)int32
{
self = [super init];
_value.int32 = int32;
_type = OF_NUMBER_INT32;
return self;
}
- initWithInt64: (int64_t)int64
{
self = [super init];
_value.int64 = int64;
_type = OF_NUMBER_INT64;
return self;
}
- initWithUInt8: (uint8_t)uint8
{
self = [super init];
_value.uint8 = uint8;
_type = OF_NUMBER_UINT8;
return self;
}
- initWithUInt16: (uint16_t)uint16
{
self = [super init];
_value.uint16 = uint16;
_type = OF_NUMBER_UINT16;
return self;
}
- initWithUInt32: (uint32_t)uint32
{
self = [super init];
_value.uint32 = uint32;
_type = OF_NUMBER_UINT32;
return self;
}
- initWithUInt64: (uint64_t)uint64
{
self = [super init];
_value.uint64 = uint64;
_type = OF_NUMBER_UINT64;
return self;
}
- initWithSize: (size_t)size
{
self = [super init];
_value.size = size;
_type = OF_NUMBER_SIZE;
return self;
}
- initWithSSize: (ssize_t)ssize
{
self = [super init];
_value.ssize = ssize;
_type = OF_NUMBER_SSIZE;
return self;
}
- initWithIntMax: (intmax_t)intmax
{
self = [super init];
_value.intmax = intmax;
_type = OF_NUMBER_INTMAX;
return self;
}
- initWithUIntMax: (uintmax_t)uintmax
{
self = [super init];
_value.uintmax = uintmax;
_type = OF_NUMBER_UINTMAX;
return self;
}
- initWithPtrDiff: (ptrdiff_t)ptrdiff
{
self = [super init];
_value.ptrdiff = ptrdiff;
_type = OF_NUMBER_PTRDIFF;
return self;
}
- initWithIntPtr: (intptr_t)intptr
{
self = [super init];
_value.intptr = intptr;
_type = OF_NUMBER_INTPTR;
return self;
}
- initWithUIntPtr: (uintptr_t)uintptr
{
self = [super init];
_value.uintptr = uintptr;
_type = OF_NUMBER_UINTPTR;
return self;
}
- initWithFloat: (float)float_
{
self = [super init];
_value.float_ = float_;
_type = OF_NUMBER_FLOAT;
return self;
}
- initWithDouble: (double)double_
{
self = [super init];
_value.double_ = double_;
_type = OF_NUMBER_DOUBLE;
return self;
}
- initWithSerialization: (OFXMLElement*)element
{
self = [super init];
|
︙ | | | ︙ | |
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
|
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
typeString = [[element attributeForName: @"type"] stringValue];
if ([typeString isEqual: @"boolean"]) {
type = OF_NUMBER_BOOL;
if ([[element stringValue] isEqual: @"YES"])
value.bool_ = YES;
else if ([[element stringValue] isEqual: @"NO"])
value.bool_ = NO;
else
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
} else if ([typeString isEqual: @"unsigned"]) {
/*
* FIXME: This will fail if the value is bigger than
* INTMAX_MAX!
*/
type = OF_NUMBER_UINTMAX;
value.uintmax = [element decimalValue];
} else if ([typeString isEqual: @"signed"]) {
type = OF_NUMBER_INTMAX;
value.intmax = [element decimalValue];
} else if ([typeString isEqual: @"float"]) {
union {
float f;
uint32_t u;
} f;
f.u = (uint32_t)[element hexadecimalValue];
type = OF_NUMBER_FLOAT;
value.float_ = f.f;
} else if ([typeString isEqual: @"double"]) {
union {
double d;
uint64_t u;
} d;
d.u = (uint64_t)[element hexadecimalValue];
type = OF_NUMBER_DOUBLE;
value.double_ = d.d;
} else
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (of_number_type_t)type
{
return type;
}
- (BOOL)boolValue
{
switch (type) {
case OF_NUMBER_BOOL:
return !!value.bool_;
case OF_NUMBER_CHAR:
return !!value.char_;
case OF_NUMBER_SHORT:
return !!value.short_;
case OF_NUMBER_INT:
return !!value.int_;
case OF_NUMBER_LONG:
return !!value.long_;
case OF_NUMBER_UCHAR:
return !!value.uchar;
case OF_NUMBER_USHORT:
return !!value.ushort;
case OF_NUMBER_UINT:
return !!value.uint;
case OF_NUMBER_ULONG:
return !!value.ulong;
case OF_NUMBER_INT8:
return !!value.int8;
case OF_NUMBER_INT16:
return !!value.int16;
case OF_NUMBER_INT32:
return !!value.int32;
case OF_NUMBER_INT64:
return !!value.int64;
case OF_NUMBER_UINT8:
return !!value.uint8;
case OF_NUMBER_UINT16:
return !!value.uint16;
case OF_NUMBER_UINT32:
return !!value.uint32;
case OF_NUMBER_UINT64:
return !!value.uint64;
case OF_NUMBER_SIZE:
return !!value.size;
case OF_NUMBER_SSIZE:
return !!value.ssize;
case OF_NUMBER_INTMAX:
return !!value.intmax;
case OF_NUMBER_UINTMAX:
return !!value.uintmax;
case OF_NUMBER_PTRDIFF:
return !!value.ptrdiff;
case OF_NUMBER_INTPTR:
return !!value.intptr;
case OF_NUMBER_UINTPTR:
return !!value.uintptr;
case OF_NUMBER_FLOAT:
return !!value.float_;
case OF_NUMBER_DOUBLE:
return !!value.double_;
default:
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
}
}
- (signed char)charValue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
|
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
typeString = [[element attributeForName: @"type"] stringValue];
if ([typeString isEqual: @"boolean"]) {
_type = OF_NUMBER_BOOL;
if ([[element stringValue] isEqual: @"YES"])
_value.bool_ = YES;
else if ([[element stringValue] isEqual: @"NO"])
_value.bool_ = NO;
else
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
} else if ([typeString isEqual: @"unsigned"]) {
/*
* FIXME: This will fail if the value is bigger than
* INTMAX_MAX!
*/
_type = OF_NUMBER_UINTMAX;
_value.uintmax = [element decimalValue];
} else if ([typeString isEqual: @"signed"]) {
_type = OF_NUMBER_INTMAX;
_value.intmax = [element decimalValue];
} else if ([typeString isEqual: @"float"]) {
union {
float f;
uint32_t u;
} f;
f.u = (uint32_t)[element hexadecimalValue];
_type = OF_NUMBER_FLOAT;
_value.float_ = f.f;
} else if ([typeString isEqual: @"double"]) {
union {
double d;
uint64_t u;
} d;
d.u = (uint64_t)[element hexadecimalValue];
_type = OF_NUMBER_DOUBLE;
_value.double_ = d.d;
} else
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (of_number_type_t)type
{
return _type;
}
- (BOOL)boolValue
{
switch (_type) {
case OF_NUMBER_BOOL:
return !!_value.bool_;
case OF_NUMBER_CHAR:
return !!_value.schar;
case OF_NUMBER_SHORT:
return !!_value.sshort;
case OF_NUMBER_INT:
return !!_value.sint;
case OF_NUMBER_LONG:
return !!_value.slong;
case OF_NUMBER_UCHAR:
return !!_value.uchar;
case OF_NUMBER_USHORT:
return !!_value.ushort;
case OF_NUMBER_UINT:
return !!_value.uint;
case OF_NUMBER_ULONG:
return !!_value.ulong;
case OF_NUMBER_INT8:
return !!_value.int8;
case OF_NUMBER_INT16:
return !!_value.int16;
case OF_NUMBER_INT32:
return !!_value.int32;
case OF_NUMBER_INT64:
return !!_value.int64;
case OF_NUMBER_UINT8:
return !!_value.uint8;
case OF_NUMBER_UINT16:
return !!_value.uint16;
case OF_NUMBER_UINT32:
return !!_value.uint32;
case OF_NUMBER_UINT64:
return !!_value.uint64;
case OF_NUMBER_SIZE:
return !!_value.size;
case OF_NUMBER_SSIZE:
return !!_value.ssize;
case OF_NUMBER_INTMAX:
return !!_value.intmax;
case OF_NUMBER_UINTMAX:
return !!_value.uintmax;
case OF_NUMBER_PTRDIFF:
return !!_value.ptrdiff;
case OF_NUMBER_INTPTR:
return !!_value.intptr;
case OF_NUMBER_UINTPTR:
return !!_value.uintptr;
case OF_NUMBER_FLOAT:
return !!_value.float_;
case OF_NUMBER_DOUBLE:
return !!_value.double_;
default:
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
}
}
- (signed char)charValue
|
︙ | | | ︙ | |
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
|
OFNumber *number;
if (![object isKindOfClass: [OFNumber class]])
return NO;
number = object;
if (type & OF_NUMBER_FLOAT || number->type & OF_NUMBER_FLOAT)
return ([number doubleValue] == [self doubleValue]);
if (type & OF_NUMBER_SIGNED || number->type & OF_NUMBER_SIGNED)
return ([number intMaxValue] == [self intMaxValue]);
return ([number uIntMaxValue] == [self uIntMaxValue]);
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
OFNumber *number;
if (![object isKindOfClass: [OFNumber class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
number = (OFNumber*)object;
if (type & OF_NUMBER_FLOAT || number->type & OF_NUMBER_FLOAT) {
double double1 = [self doubleValue];
double double2 = [number doubleValue];
if (double1 > double2)
return OF_ORDERED_DESCENDING;
if (double1 < double2)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
} else if (type & OF_NUMBER_SIGNED || number->type & OF_NUMBER_SIGNED) {
intmax_t int1 = [self intMaxValue];
intmax_t int2 = [number intMaxValue];
if (int1 > int2)
return OF_ORDERED_DESCENDING;
if (int1 < int2)
return OF_ORDERED_ASCENDING;
|
|
|
|
>
|
|
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
|
OFNumber *number;
if (![object isKindOfClass: [OFNumber class]])
return NO;
number = object;
if (_type & OF_NUMBER_FLOAT || number->_type & OF_NUMBER_FLOAT)
return ([number doubleValue] == [self doubleValue]);
if (_type & OF_NUMBER_SIGNED || number->_type & OF_NUMBER_SIGNED)
return ([number intMaxValue] == [self intMaxValue]);
return ([number uIntMaxValue] == [self uIntMaxValue]);
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
OFNumber *number;
if (![object isKindOfClass: [OFNumber class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
number = (OFNumber*)object;
if (_type & OF_NUMBER_FLOAT || number->_type & OF_NUMBER_FLOAT) {
double double1 = [self doubleValue];
double double2 = [number doubleValue];
if (double1 > double2)
return OF_ORDERED_DESCENDING;
if (double1 < double2)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
} else if (_type & OF_NUMBER_SIGNED ||
number->_type & OF_NUMBER_SIGNED) {
intmax_t int1 = [self intMaxValue];
intmax_t int2 = [number intMaxValue];
if (int1 > int2)
return OF_ORDERED_DESCENDING;
if (int1 < int2)
return OF_ORDERED_ASCENDING;
|
︙ | | | ︙ | |
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
|
return OF_ORDERED_SAME;
}
}
- (uint32_t)hash
{
of_number_type_t type_ = type;
uint32_t hash;
/* Do we really need signed to represent this number? */
if (type_ & OF_NUMBER_SIGNED && [self intMaxValue] >= 0)
type_ &= ~OF_NUMBER_SIGNED;
/* Do we really need floating point to represent this number? */
if (type_ & OF_NUMBER_FLOAT) {
double v = [self doubleValue];
if (v < 0) {
if (v == [self intMaxValue]) {
type_ &= ~OF_NUMBER_FLOAT;
type_ |= OF_NUMBER_SIGNED;
}
} else {
if (v == [self uIntMaxValue])
type_ &= ~OF_NUMBER_FLOAT;
}
}
OF_HASH_INIT(hash);
if (type_ & OF_NUMBER_FLOAT) {
union {
double d;
uint8_t b[sizeof(double)];
} d;
uint_fast8_t i;
d.d = OF_BSWAP_DOUBLE_IF_BE([self doubleValue]);
for (i = 0; i < sizeof(double); i++)
OF_HASH_ADD(hash, d.b[i]);
} else if (type_ & OF_NUMBER_SIGNED) {
intmax_t v = [self intMaxValue] * -1;
while (v != 0) {
OF_HASH_ADD(hash, v & 0xFF);
v >>= 8;
}
|
|
|
|
|
|
|
|
|
|
|
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
|
return OF_ORDERED_SAME;
}
}
- (uint32_t)hash
{
of_number_type_t type = _type;
uint32_t hash;
/* Do we really need signed to represent this number? */
if (type & OF_NUMBER_SIGNED && [self intMaxValue] >= 0)
type &= ~OF_NUMBER_SIGNED;
/* Do we really need floating point to represent this number? */
if (type & OF_NUMBER_FLOAT) {
double v = [self doubleValue];
if (v < 0) {
if (v == [self intMaxValue]) {
type &= ~OF_NUMBER_FLOAT;
type |= OF_NUMBER_SIGNED;
}
} else {
if (v == [self uIntMaxValue])
type &= ~OF_NUMBER_FLOAT;
}
}
OF_HASH_INIT(hash);
if (type & OF_NUMBER_FLOAT) {
union {
double d;
uint8_t b[sizeof(double)];
} d;
uint_fast8_t i;
d.d = OF_BSWAP_DOUBLE_IF_BE([self doubleValue]);
for (i = 0; i < sizeof(double); i++)
OF_HASH_ADD(hash, d.b[i]);
} else if (type & OF_NUMBER_SIGNED) {
intmax_t v = [self intMaxValue] * -1;
while (v != 0) {
OF_HASH_ADD(hash, v & 0xFF);
v >>= 8;
}
|
︙ | | | ︙ | |
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
|
- (OFNumber*)numberByDecreasing
{
CALCULATE3(- 1)
}
- (OFNumber*)remainderOfDivisionWithNumber: (OFNumber*)number
{
switch (type) {
case OF_NUMBER_BOOL:
return [OFNumber numberWithBool:
value.bool_ % [number boolValue]];
case OF_NUMBER_CHAR:
return [OFNumber numberWithChar:
value.char_ % [number charValue]];
case OF_NUMBER_SHORT:
return [OFNumber numberWithShort:
value.short_ % [number shortValue]];
case OF_NUMBER_INT:
return [OFNumber numberWithInt: value.int_ % [number intValue]];
case OF_NUMBER_LONG:
return [OFNumber numberWithLong:
value.long_ % [number longValue]];
case OF_NUMBER_UCHAR:
return [OFNumber numberWithUnsignedChar:
value.uchar % [number unsignedCharValue]];
case OF_NUMBER_USHORT:
return [OFNumber numberWithUnsignedShort:
value.ushort % [number unsignedShortValue]];
case OF_NUMBER_UINT:
return [OFNumber numberWithUnsignedInt:
value.uint % [number unsignedIntValue]];
case OF_NUMBER_ULONG:
return [OFNumber numberWithUnsignedLong:
value.ulong % [number unsignedLongValue]];
case OF_NUMBER_INT8:
return [OFNumber numberWithInt8:
value.int8 % [number int8Value]];
case OF_NUMBER_INT16:
return [OFNumber numberWithInt16:
value.int16 % [number int16Value]];
case OF_NUMBER_INT32:
return [OFNumber numberWithInt32:
value.int32 % [number int32Value]];
case OF_NUMBER_INT64:
return [OFNumber numberWithInt64:
value.int64 % [number int64Value]];
case OF_NUMBER_UINT8:
return [OFNumber numberWithUInt8:
value.uint8 % [number uInt8Value]];
case OF_NUMBER_UINT16:
return [OFNumber numberWithUInt16:
value.uint16 % [number uInt16Value]];
case OF_NUMBER_UINT32:
return [OFNumber numberWithUInt32:
value.uint32 % [number uInt32Value]];
case OF_NUMBER_UINT64:
return [OFNumber numberWithUInt64:
value.uint64 % [number uInt64Value]];
case OF_NUMBER_SIZE:
return [OFNumber numberWithSize:
value.size % [number sizeValue]];
case OF_NUMBER_SSIZE:
return [OFNumber numberWithSSize:
value.ssize % [number sSizeValue]];
case OF_NUMBER_INTMAX:
return [OFNumber numberWithIntMax:
value.intmax % [number intMaxValue]];
case OF_NUMBER_UINTMAX:
return [OFNumber numberWithUIntMax:
value.uintmax % [number uIntMaxValue]];
case OF_NUMBER_PTRDIFF:
return [OFNumber numberWithPtrDiff:
value.ptrdiff % [number ptrDiffValue]];
case OF_NUMBER_INTPTR:
return [OFNumber numberWithIntPtr:
value.intptr % [number intPtrValue]];
case OF_NUMBER_UINTPTR:
return [OFNumber numberWithUIntPtr:
value.uintptr % [number uIntPtrValue]];
case OF_NUMBER_FLOAT:
return [OFNumber
numberWithFloat: fmodf(value.float_, [number floatValue])];
case OF_NUMBER_DOUBLE:
return [OFNumber numberWithDouble:
fmod(value.double_, [number doubleValue])];
default:
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
}
}
- copy
{
return [self retain];
}
- (OFString*)description
{
OFMutableString *ret;
switch (type) {
case OF_NUMBER_BOOL:
return (value.bool_ ? @"YES" : @"NO");
case OF_NUMBER_UCHAR:
case OF_NUMBER_USHORT:
case OF_NUMBER_UINT:
case OF_NUMBER_ULONG:
case OF_NUMBER_UINT8:
case OF_NUMBER_UINT16:
case OF_NUMBER_UINT32:
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
|
- (OFNumber*)numberByDecreasing
{
CALCULATE3(- 1)
}
- (OFNumber*)remainderOfDivisionWithNumber: (OFNumber*)number
{
switch (_type) {
case OF_NUMBER_BOOL:
return [OFNumber numberWithBool:
_value.bool_ % [number boolValue]];
case OF_NUMBER_CHAR:
return [OFNumber numberWithChar:
_value.schar % [number charValue]];
case OF_NUMBER_SHORT:
return [OFNumber numberWithShort:
_value.sshort % [number shortValue]];
case OF_NUMBER_INT:
return [OFNumber numberWithInt:
_value.sint % [number intValue]];
case OF_NUMBER_LONG:
return [OFNumber numberWithLong:
_value.slong % [number longValue]];
case OF_NUMBER_UCHAR:
return [OFNumber numberWithUnsignedChar:
_value.uchar % [number unsignedCharValue]];
case OF_NUMBER_USHORT:
return [OFNumber numberWithUnsignedShort:
_value.ushort % [number unsignedShortValue]];
case OF_NUMBER_UINT:
return [OFNumber numberWithUnsignedInt:
_value.uint % [number unsignedIntValue]];
case OF_NUMBER_ULONG:
return [OFNumber numberWithUnsignedLong:
_value.ulong % [number unsignedLongValue]];
case OF_NUMBER_INT8:
return [OFNumber numberWithInt8:
_value.int8 % [number int8Value]];
case OF_NUMBER_INT16:
return [OFNumber numberWithInt16:
_value.int16 % [number int16Value]];
case OF_NUMBER_INT32:
return [OFNumber numberWithInt32:
_value.int32 % [number int32Value]];
case OF_NUMBER_INT64:
return [OFNumber numberWithInt64:
_value.int64 % [number int64Value]];
case OF_NUMBER_UINT8:
return [OFNumber numberWithUInt8:
_value.uint8 % [number uInt8Value]];
case OF_NUMBER_UINT16:
return [OFNumber numberWithUInt16:
_value.uint16 % [number uInt16Value]];
case OF_NUMBER_UINT32:
return [OFNumber numberWithUInt32:
_value.uint32 % [number uInt32Value]];
case OF_NUMBER_UINT64:
return [OFNumber numberWithUInt64:
_value.uint64 % [number uInt64Value]];
case OF_NUMBER_SIZE:
return [OFNumber numberWithSize:
_value.size % [number sizeValue]];
case OF_NUMBER_SSIZE:
return [OFNumber numberWithSSize:
_value.ssize % [number sSizeValue]];
case OF_NUMBER_INTMAX:
return [OFNumber numberWithIntMax:
_value.intmax % [number intMaxValue]];
case OF_NUMBER_UINTMAX:
return [OFNumber numberWithUIntMax:
_value.uintmax % [number uIntMaxValue]];
case OF_NUMBER_PTRDIFF:
return [OFNumber numberWithPtrDiff:
_value.ptrdiff % [number ptrDiffValue]];
case OF_NUMBER_INTPTR:
return [OFNumber numberWithIntPtr:
_value.intptr % [number intPtrValue]];
case OF_NUMBER_UINTPTR:
return [OFNumber numberWithUIntPtr:
_value.uintptr % [number uIntPtrValue]];
case OF_NUMBER_FLOAT:
return [OFNumber numberWithFloat:
fmodf(_value.float_, [number floatValue])];
case OF_NUMBER_DOUBLE:
return [OFNumber numberWithDouble:
fmod(_value.double_, [number doubleValue])];
default:
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
}
}
- copy
{
return [self retain];
}
- (OFString*)description
{
OFMutableString *ret;
switch (_type) {
case OF_NUMBER_BOOL:
return (_value.bool_ ? @"YES" : @"NO");
case OF_NUMBER_UCHAR:
case OF_NUMBER_USHORT:
case OF_NUMBER_UINT:
case OF_NUMBER_ULONG:
case OF_NUMBER_UINT8:
case OF_NUMBER_UINT16:
case OF_NUMBER_UINT32:
|
︙ | | | ︙ | |
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
|
case OF_NUMBER_INT64:
case OF_NUMBER_SSIZE:
case OF_NUMBER_INTMAX:
case OF_NUMBER_PTRDIFF:
case OF_NUMBER_INTPTR:
return [OFString stringWithFormat: @"%jd", [self intMaxValue]];
case OF_NUMBER_FLOAT:
ret = [OFMutableString stringWithFormat: @"%g", value.float_];
if (![ret containsString: @"."])
[ret appendString: @".0"];
[ret makeImmutable];
return ret;
case OF_NUMBER_DOUBLE:
ret = [OFMutableString stringWithFormat: @"%lg", value.double_];
if (![ret containsString: @"."])
[ret appendString: @".0"];
[ret makeImmutable];
return ret;
|
|
|
>
|
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
|
case OF_NUMBER_INT64:
case OF_NUMBER_SSIZE:
case OF_NUMBER_INTMAX:
case OF_NUMBER_PTRDIFF:
case OF_NUMBER_INTPTR:
return [OFString stringWithFormat: @"%jd", [self intMaxValue]];
case OF_NUMBER_FLOAT:
ret = [OFMutableString stringWithFormat: @"%g", _value.float_];
if (![ret containsString: @"."])
[ret appendString: @".0"];
[ret makeImmutable];
return ret;
case OF_NUMBER_DOUBLE:
ret = [OFMutableString stringWithFormat: @"%lg",
_value.double_];
if (![ret containsString: @"."])
[ret appendString: @".0"];
[ret makeImmutable];
return ret;
|
︙ | | | ︙ | |
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
|
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: [self description]];
switch (type) {
case OF_NUMBER_BOOL:
[element addAttributeWithName: @"type"
stringValue: @"boolean"];
break;
case OF_NUMBER_UCHAR:
case OF_NUMBER_USHORT:
case OF_NUMBER_UINT:
|
|
|
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
|
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: [self description]];
switch (_type) {
case OF_NUMBER_BOOL:
[element addAttributeWithName: @"type"
stringValue: @"boolean"];
break;
case OF_NUMBER_UCHAR:
case OF_NUMBER_USHORT:
case OF_NUMBER_UINT:
|
︙ | | | ︙ | |
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
|
break;
case OF_NUMBER_FLOAT:;
union {
float f;
uint32_t u;
} f;
f.f = value.float_;
[element addAttributeWithName: @"type"
stringValue: @"float"];
[element setStringValue:
[OFString stringWithFormat: @"%08" PRIx32, f.u]];
break;
case OF_NUMBER_DOUBLE:;
union {
double d;
uint64_t u;
} d;
d.d = value.double_;
[element addAttributeWithName: @"type"
stringValue: @"double"];
[element setStringValue:
[OFString stringWithFormat: @"%016" PRIx64, d.u]];
break;
|
|
|
|
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
|
break;
case OF_NUMBER_FLOAT:;
union {
float f;
uint32_t u;
} f;
f.f = _value.float_;
[element addAttributeWithName: @"type"
stringValue: @"float"];
[element setStringValue:
[OFString stringWithFormat: @"%08" PRIx32, f.u]];
break;
case OF_NUMBER_DOUBLE:;
union {
double d;
uint64_t u;
} d;
d.d = _value.double_;
[element addAttributeWithName: @"type"
stringValue: @"double"];
[element setStringValue:
[OFString stringWithFormat: @"%016" PRIx64, d.u]];
break;
|
︙ | | | ︙ | |
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
|
return [element autorelease];
}
- (OFString*)JSONRepresentation
{
double doubleValue;
if (type == OF_NUMBER_BOOL)
return (value.bool_ ? @"true" : @"false");
doubleValue = [self doubleValue];
if (isinf(doubleValue)) {
if (doubleValue > 0)
return @"Infinity";
else
return @"-Infinity";
}
return [self description];
}
@end
|
|
|
|
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
|
return [element autorelease];
}
- (OFString*)JSONRepresentation
{
double doubleValue;
if (_type == OF_NUMBER_BOOL)
return (_value.bool_ ? @"true" : @"false");
doubleValue = [self doubleValue];
if (isinf(doubleValue)) {
if (doubleValue > 0)
return @"Infinity";
else
return @"-Infinity";
}
return [self description];
}
@end
|
Modified src/OFObject.h
from [a61f98d08c]
to [7e8147f893].
︙ | | | ︙ | |
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
/*!
* @brief The root class for all other classes inside ObjFW.
*/
@interface OFObject <OFObject>
{
@public
Class isa;
}
/*!
* @brief A method which is called once when the class is loaded into the
* runtime.
*
* Derived classes can overide this to execute their own code when the class is
|
|
|
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
/*!
* @brief The root class for all other classes inside ObjFW.
*/
@interface OFObject <OFObject>
{
@public
Class _isa;
}
/*!
* @brief A method which is called once when the class is loaded into the
* runtime.
*
* Derived classes can overide this to execute their own code when the class is
|
︙ | | | ︙ | |
Modified src/OFPlugin.h
from [00c2e927a6]
to [ba7c63f3e9].
︙ | | | ︙ | |
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
#endif
/*!
* @brief Provides a system for loading plugins at runtime.
*/
@interface OFPlugin: OFObject
{
of_plugin_handle_t handle;
}
/*!
* @brief Loads a plugin from a file.
*
* @param path Path to the plugin file. The suffix is appended automatically.
* @return The loaded plugin
*/
+ (id)pluginFromFile: (OFString*)path;
@end
|
|
|
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
#endif
/*!
* @brief Provides a system for loading plugins at runtime.
*/
@interface OFPlugin: OFObject
{
of_plugin_handle_t _handle;
}
/*!
* @brief Loads a plugin from a file.
*
* @param path Path to the plugin file. The suffix is appended automatically.
* @return The loaded plugin
*/
+ (id)pluginFromFile: (OFString*)path;
@end
|
Modified src/OFPlugin.m
from [929f009f47]
to [ae3dcbbf47].
︙ | | | ︙ | |
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
|
initPlugin = (OFPlugin*(*)(void))dlsym(handle, "init_plugin");
if (initPlugin == NULL || (plugin = initPlugin()) == nil) {
dlclose(handle);
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
plugin->handle = handle;
return plugin;
}
- init
{
if (object_getClass(self) == [OFPlugin class]) {
@try {
[self doesNotRecognizeSelector: _cmd];
abort();
} @catch (id e) {
[self release];
@throw e;
}
}
return [super init];
}
- (void)dealloc
{
of_plugin_handle_t h = handle;
[super dealloc];
dlclose(h);
}
@end
|
|
|
|
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
|
initPlugin = (OFPlugin*(*)(void))dlsym(handle, "init_plugin");
if (initPlugin == NULL || (plugin = initPlugin()) == nil) {
dlclose(handle);
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
plugin->_handle = handle;
return plugin;
}
- init
{
if (object_getClass(self) == [OFPlugin class]) {
@try {
[self doesNotRecognizeSelector: _cmd];
abort();
} @catch (id e) {
[self release];
@throw e;
}
}
return [super init];
}
- (void)dealloc
{
of_plugin_handle_t h = _handle;
[super dealloc];
dlclose(h);
}
@end
|
Modified src/OFProcess.h
from [4eeb2e3155]
to [97b7b3ccc7].
︙ | | | ︙ | |
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
/*!
* @brief A class for stream-like communication with a newly created process.
*/
@interface OFProcess: OFStream
{
#ifndef _WIN32
pid_t pid;
int readPipe[2], writePipe[2];
#else
HANDLE process, readPipe[2], writePipe[2];
#endif
int status;
BOOL atEndOfStream;
}
/*!
* @brief Creates a new OFProcess with the specified program and invokes the
* program.
*
* @param program The program to execute. If it does not start with a slash, the
|
|
|
|
|
|
|
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
/*!
* @brief A class for stream-like communication with a newly created process.
*/
@interface OFProcess: OFStream
{
#ifndef _WIN32
pid_t _pid;
int _readPipe[2], _writePipe[2];
#else
HANDLE _process, _readPipe[2], _writePipe[2];
#endif
int _status;
BOOL _atEndOfStream;
}
/*!
* @brief Creates a new OFProcess with the specified program and invokes the
* program.
*
* @param program The program to execute. If it does not start with a slash, the
|
︙ | | | ︙ | |
Modified src/OFProcess.m
from [8542470fa0]
to [ef90137219].
︙ | | | ︙ | |
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
arguments: (OFArray*)arguments
environment: (OFDictionary*)environment
{
self = [super init];
@try {
#ifndef _WIN32
if (pipe(readPipe) != 0 || pipe(writePipe) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
switch ((pid = fork())) {
case 0:;
OFString **objects = [arguments objects];
size_t i, count = [arguments count];
char **argv;
argv = [self allocMemoryWithSize: sizeof(char*)
count: count + 2];
|
|
|
|
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
arguments: (OFArray*)arguments
environment: (OFDictionary*)environment
{
self = [super init];
@try {
#ifndef _WIN32
if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
switch ((_pid = fork())) {
case 0:;
OFString **objects = [arguments objects];
size_t i, count = [arguments count];
char **argv;
argv = [self allocMemoryWithSize: sizeof(char*)
count: count + 2];
|
︙ | | | ︙ | |
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
OF_environmentForDictionary: environment];
#else
environ = [self
OF_environmentForDictionary: environment];
#endif
}
close(readPipe[0]);
close(writePipe[1]);
dup2(writePipe[0], 0);
dup2(readPipe[1], 1);
execvp([program cStringWithEncoding:
OF_STRING_ENCODING_NATIVE], argv);
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
case -1:
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
default:
close(readPipe[1]);
close(writePipe[0]);
break;
}
#else
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
STARTUPINFOW si;
void *pool;
OFMutableString *argumentsString;
OFEnumerator *enumerator;
OFString *argument;
uint16_t *argumentsCopy;
size_t length;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&readPipe[0], &readPipe[1], &sa, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!SetHandleInformation(readPipe[0], HANDLE_FLAG_INHERIT, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!CreatePipe(&writePipe[0], &writePipe[1], &sa, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!SetHandleInformation(writePipe[1], HANDLE_FLAG_INHERIT, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = writePipe[0];
si.hStdOutput = readPipe[1];
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
pool = objc_autoreleasePoolPush();
argumentsString =
[OFMutableString stringWithString: programName];
|
|
|
|
|
|
|
>
>
>
|
>
|
<
<
<
|
|
|
|
|
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
OF_environmentForDictionary: environment];
#else
environ = [self
OF_environmentForDictionary: environment];
#endif
}
close(_readPipe[0]);
close(_writePipe[1]);
dup2(_writePipe[0], 0);
dup2(_readPipe[1], 1);
execvp([program cStringWithEncoding:
OF_STRING_ENCODING_NATIVE], argv);
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
case -1:
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
default:
close(_readPipe[1]);
close(_writePipe[0]);
break;
}
#else
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
STARTUPINFOW si;
void *pool;
OFMutableString *argumentsString;
OFEnumerator *enumerator;
OFString *argument;
uint16_t *argumentsCopy;
size_t length;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!SetHandleInformation(_readPipe[0], HANDLE_FLAG_INHERIT, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!CreatePipe(&_writePipe[0], &_writePipe[1], &sa, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
if (!SetHandleInformation(_writePipe[1],
HANDLE_FLAG_INHERIT, 0))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = _writePipe[0];
si.hStdOutput = _readPipe[1];
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
pool = objc_autoreleasePoolPush();
argumentsString =
[OFMutableString stringWithString: programName];
|
︙ | | | ︙ | |
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
exceptionWithClass: [self class]];
} @finally {
[self freeMemory: argumentsCopy];
}
objc_autoreleasePoolPop(pool);
process = pi.hProcess;
CloseHandle(pi.hThread);
CloseHandle(readPipe[1]);
CloseHandle(writePipe[0]);
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#ifndef _WIN32
- (char**)OF_environmentForDictionary: (OFDictionary*)environment
{
OFEnumerator *keyEnumerator, *objectEnumerator;
char **envp;
size_t i, count;
|
|
|
|
>
>
>
>
>
>
>
|
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
exceptionWithClass: [self class]];
} @finally {
[self freeMemory: argumentsCopy];
}
objc_autoreleasePoolPop(pool);
_process = pi.hProcess;
CloseHandle(pi.hThread);
CloseHandle(_readPipe[1]);
CloseHandle(_writePipe[0]);
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[self close];
[super dealloc];
}
#ifndef _WIN32
- (char**)OF_environmentForDictionary: (OFDictionary*)environment
{
OFEnumerator *keyEnumerator, *objectEnumerator;
char **envp;
size_t i, count;
|
︙ | | | ︙ | |
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
|
return [env items];
}
#endif
- (BOOL)lowlevelIsAtEndOfStream
{
#ifndef _WIN32
if (readPipe[0] == -1)
#else
if (readPipe[0] == NULL)
#endif
return YES;
return atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
#ifndef _WIN32
ssize_t ret;
#else
DWORD ret;
#endif
#ifndef _WIN32
if (readPipe[0] == -1 || atEndOfStream ||
(ret = read(readPipe[0], buffer, length)) < 0) {
#else
if (readPipe[0] == NULL || atEndOfStream ||
!ReadFile(readPipe[0], buffer, length, &ret, NULL)) {
if (GetLastError() == ERROR_BROKEN_PIPE) {
atEndOfStream = YES;
return 0;
}
#endif
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
if (ret == 0)
atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
#ifndef _WIN32
if (writePipe[1] == -1 || atEndOfStream ||
write(writePipe[1], buffer, length) < length)
#else
DWORD ret;
if (writePipe[1] == NULL || atEndOfStream ||
!WriteFile(writePipe[1], buffer, length, &ret, NULL) ||
ret < length)
#endif
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
- (void)dealloc
{
[self close];
[super dealloc];
}
- (int)fileDescriptorForReading
{
#ifndef _WIN32
return readPipe[0];
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (int)fileDescriptorForWriting
{
#ifndef _WIN32
return writePipe[1];
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (void)closeForWriting
{
#ifndef _WIN32
if (writePipe[1] != -1)
close(writePipe[1]);
writePipe[1] = -1;
#else
if (writePipe[1] != NULL)
CloseHandle(writePipe[1]);
writePipe[1] = NULL;
#endif
}
- (void)close
{
#ifndef _WIN32
if (readPipe[0] != -1)
close(readPipe[0]);
if (writePipe[1] != -1)
close(writePipe[1]);
if (pid != -1) {
kill(pid, SIGKILL);
waitpid(pid, &status, WNOHANG);
}
pid = -1;
readPipe[0] = -1;
writePipe[1] = -1;
#else
if (readPipe[0] != NULL)
CloseHandle(readPipe[0]);
if (writePipe[1] != NULL)
CloseHandle(writePipe[1]);
if (process != INVALID_HANDLE_VALUE) {
TerminateProcess(process, 0);
CloseHandle(process);
}
process = INVALID_HANDLE_VALUE;
readPipe[0] = NULL;
writePipe[1] = NULL;
#endif
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
|
return [env items];
}
#endif
- (BOOL)lowlevelIsAtEndOfStream
{
#ifndef _WIN32
if (_readPipe[0] == -1)
#else
if (_readPipe[0] == NULL)
#endif
return YES;
return _atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
#ifndef _WIN32
ssize_t ret;
#else
DWORD ret;
#endif
#ifndef _WIN32
if (_readPipe[0] == -1 || _atEndOfStream ||
(ret = read(_readPipe[0], buffer, length)) < 0) {
#else
if (_readPipe[0] == NULL || _atEndOfStream ||
!ReadFile(_readPipe[0], buffer, length, &ret, NULL)) {
if (GetLastError() == ERROR_BROKEN_PIPE) {
_atEndOfStream = YES;
return 0;
}
#endif
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
if (ret == 0)
_atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
#ifndef _WIN32
if (_writePipe[1] == -1 || _atEndOfStream ||
write(_writePipe[1], buffer, length) < length)
#else
DWORD ret;
if (_writePipe[1] == NULL || _atEndOfStream ||
!WriteFile(_writePipe[1], buffer, length, &ret, NULL) ||
ret < length)
#endif
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
- (int)fileDescriptorForReading
{
#ifndef _WIN32
return _readPipe[0];
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (int)fileDescriptorForWriting
{
#ifndef _WIN32
return _writePipe[1];
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (void)closeForWriting
{
#ifndef _WIN32
if (_writePipe[1] != -1)
close(_writePipe[1]);
_writePipe[1] = -1;
#else
if (_writePipe[1] != NULL)
CloseHandle(_writePipe[1]);
_writePipe[1] = NULL;
#endif
}
- (void)close
{
#ifndef _WIN32
if (_readPipe[0] != -1)
close(_readPipe[0]);
if (_writePipe[1] != -1)
close(_writePipe[1]);
if (_pid != -1) {
kill(_pid, SIGKILL);
waitpid(_pid, &_status, WNOHANG);
}
_pid = -1;
_readPipe[0] = -1;
_writePipe[1] = -1;
#else
if (_readPipe[0] != NULL)
CloseHandle(_readPipe[0]);
if (_writePipe[1] != NULL)
CloseHandle(_writePipe[1]);
if (_process != INVALID_HANDLE_VALUE) {
TerminateProcess(_process, 0);
CloseHandle(_process);
}
_process = INVALID_HANDLE_VALUE;
_readPipe[0] = NULL;
_writePipe[1] = NULL;
#endif
}
@end
|
Modified src/OFRecursiveMutex.h
from [b00b0eb498]
to [5b6f8dec9f].
︙ | | | ︙ | |
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/*!
* @brief A class for creating mutual exclusions which can be entered
* recursively.
*/
@interface OFRecursiveMutex: OFObject <OFLocking>
{
of_rmutex_t rmutex;
BOOL initialized;
OFString *name;
}
/*!
* @brief Creates a new recursive mutex.
*
* @return A new autoreleased recursive mutex.
*/
+ (instancetype)mutex;
@end
|
|
|
|
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/*!
* @brief A class for creating mutual exclusions which can be entered
* recursively.
*/
@interface OFRecursiveMutex: OFObject <OFLocking>
{
of_rmutex_t _rmutex;
BOOL _initialized;
OFString *_name;
}
/*!
* @brief Creates a new recursive mutex.
*
* @return A new autoreleased recursive mutex.
*/
+ (instancetype)mutex;
@end
|
Modified src/OFRecursiveMutex.m
from [216e595238]
to [42996d602b].
︙ | | | ︙ | |
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_rmutex_new(&rmutex)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
initialized = YES;
return self;
}
- (void)lock
{
if (!of_rmutex_lock(&rmutex))
@throw [OFLockFailedException exceptionWithClass: [self class]
lock: self];
}
- (BOOL)tryLock
{
return of_rmutex_trylock(&rmutex);
}
- (void)unlock
{
if (!of_rmutex_unlock(&rmutex))
@throw [OFUnlockFailedException exceptionWithClass: [self class]
lock: self];
}
- (void)setName: (OFString*)name_
{
OF_SETTER(name, name_, YES, 1)
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (OFString*)description
{
if (name == nil)
return [super description];
return [OFString stringWithFormat: @"<%@: %@>", [self className], name];
}
- (void)dealloc
{
if (initialized)
if (!of_rmutex_free(&rmutex))
@throw [OFStillLockedException
exceptionWithClass: [self class]
lock: self];
[name release];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
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
|
return [[[self alloc] init] autorelease];
}
- init
{
self = [super init];
if (!of_rmutex_new(&_rmutex)) {
Class c = [self class];
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = YES;
return self;
}
- (void)lock
{
if (!of_rmutex_lock(&_rmutex))
@throw [OFLockFailedException exceptionWithClass: [self class]
lock: self];
}
- (BOOL)tryLock
{
return of_rmutex_trylock(&_rmutex);
}
- (void)unlock
{
if (!of_rmutex_unlock(&_rmutex))
@throw [OFUnlockFailedException exceptionWithClass: [self class]
lock: self];
}
- (void)setName: (OFString*)name
{
OF_SETTER(_name, name, YES, 1)
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (OFString*)description
{
if (_name == nil)
return [super description];
return [OFString stringWithFormat: @"<%@: %@>",
[self className], _name];
}
- (void)dealloc
{
if (_initialized)
if (!of_rmutex_free(&_rmutex))
@throw [OFStillLockedException
exceptionWithClass: [self class]
lock: self];
[_name release];
[super dealloc];
}
@end
|
Modified src/OFRunLoop.h
from [ce454681f1]
to [8c2fa8ebb3].
︙ | | | ︙ | |
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@class OFMutableDictionary;
/*!
* @brief A class providing a run loop for the application and its processes.
*/
@interface OFRunLoop: OFObject
{
OFSortedList *timersQueue;
#ifdef OF_HAVE_THREADS
OFMutex *timersQueueLock;
#endif
OFStreamObserver *streamObserver;
OFMutableDictionary *readQueues;
volatile BOOL running;
}
/*!
* @brief Returns the main run loop.
*
* @return The main run loop
*/
|
|
|
|
|
|
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@class OFMutableDictionary;
/*!
* @brief A class providing a run loop for the application and its processes.
*/
@interface OFRunLoop: OFObject
{
OFSortedList *_timersQueue;
#ifdef OF_HAVE_THREADS
OFMutex *_timersQueueLock;
#endif
OFStreamObserver *_streamObserver;
OFMutableDictionary *_readQueues;
volatile BOOL _running;
}
/*!
* @brief Returns the main run loop.
*
* @return The main run loop
*/
|
︙ | | | ︙ | |
Modified src/OFRunLoop.m
from [9ee569b5cb]
to [d21ff8bef4].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#import "OFDate.h"
#import "autorelease.h"
#import "macros.h"
static OFRunLoop *mainRunLoop = nil;
@interface OFRunLoop_ReadQueueItem: OFObject
{
@public
void *buffer;
size_t length;
id target;
SEL selector;
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_block_t block;
#endif
}
@end
@interface OFRunLoop_ExactReadQueueItem: OFObject
{
@public
void *buffer;
size_t exactLength, readLength;
id target;
SEL selector;
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_block_t block;
#endif
}
@end
@interface OFRunLoop_ReadLineQueueItem: OFObject
{
@public
of_string_encoding_t encoding;
id target;
SEL selector;
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_line_block_t block;
#endif
}
@end
@interface OFRunLoop_AcceptQueueItem: OFObject
{
@public
id target;
SEL selector;
#ifdef OF_HAVE_BLOCKS
of_tcpsocket_async_accept_block_t block;
#endif
}
@end
@implementation OFRunLoop_ReadQueueItem
- (void)dealloc
{
[target release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
[super dealloc];
}
@end
@implementation OFRunLoop_ExactReadQueueItem
- (void)dealloc
{
[target release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
[super dealloc];
}
@end
@implementation OFRunLoop_ReadLineQueueItem
- (void)dealloc
{
[target release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
[super dealloc];
}
@end
@implementation OFRunLoop_AcceptQueueItem
- (void)dealloc
{
[target release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
[super dealloc];
}
@end
@implementation OFRunLoop
+ (OFRunLoop*)mainRunLoop
{
return [[mainRunLoop retain] autorelease];
}
|
|
<
<
|
|
>
>
>
>
>
>
|
>
>
|
<
<
<
<
|
>
>
|
<
<
<
|
>
|
<
<
|
>
>
>
>
>
>
>
>
>
>
<
<
|
<
>
>
<
<
|
<
>
>
<
<
|
<
>
>
<
<
|
<
>
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#import "OFDate.h"
#import "autorelease.h"
#import "macros.h"
static OFRunLoop *mainRunLoop = nil;
@interface OFRunLoop_QueueItem: OFObject
{
@public
id _target;
SEL _selector;
}
@end
@interface OFRunLoop_ReadQueueItem: OFRunLoop_QueueItem
{
@public
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_block_t _block;
#endif
void *_buffer;
size_t _length;
}
@end
@interface OFRunLoop_ExactReadQueueItem: OFRunLoop_QueueItem
{
@public
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_block_t _block;
#endif
void *_buffer;
size_t _exactLength, _readLength;
}
@end
@interface OFRunLoop_ReadLineQueueItem: OFRunLoop_QueueItem
{
@public
#ifdef OF_HAVE_BLOCKS
of_stream_async_read_line_block_t _block;
#endif
of_string_encoding_t _encoding;
}
@end
@interface OFRunLoop_AcceptQueueItem: OFRunLoop_QueueItem
{
@public
#ifdef OF_HAVE_BLOCKS
of_tcpsocket_async_accept_block_t _block;
#endif
}
@end
@implementation OFRunLoop_QueueItem
- (void)dealloc
{
[_target release];
[super dealloc];
}
@end
@implementation OFRunLoop_ReadQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
[_block release];
[super dealloc];
}
#endif
@end
@implementation OFRunLoop_ExactReadQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
[_block release];
[super dealloc];
}
#endif
@end
@implementation OFRunLoop_ReadLineQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
[_block release];
[super dealloc];
}
#endif
@end
@implementation OFRunLoop_AcceptQueueItem
#ifdef OF_HAVE_BLOCKS
- (void)dealloc
{
[_block release];
[super dealloc];
}
#endif
@end
@implementation OFRunLoop
+ (OFRunLoop*)mainRunLoop
{
return [[mainRunLoop retain] autorelease];
}
|
︙ | | | ︙ | |
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
|
{
mainRunLoop = [runLoop retain];
}
#define ADD(type, code) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFList *queue = [runLoop->readQueues objectForKey: stream]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[runLoop->readQueues setObject: queue \
forKey: stream]; \
} \
\
if ([queue count] == 0) \
[runLoop->streamObserver addStreamForReading: stream]; \
\
queueItem = [[[type alloc] init] autorelease]; \
code \
[queue appendObject: queueItem]; \
\
objc_autoreleasePoolPop(pool);
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
length: (size_t)length
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ReadQueueItem, {
queueItem->buffer = buffer;
queueItem->length = length;
queueItem->target = [target retain];
queueItem->selector = selector;
})
}
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
exactLength: (size_t)exactLength
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ExactReadQueueItem, {
queueItem->buffer = buffer;
queueItem->exactLength = exactLength;
queueItem->target = [target retain];
queueItem->selector = selector;
})
}
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
encoding: (of_string_encoding_t)encoding
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ReadLineQueueItem, {
queueItem->encoding = encoding;
queueItem->target = [target retain];
queueItem->selector = selector;
})
}
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_AcceptQueueItem, {
queueItem->target = [target retain];
queueItem->selector = selector;
})
}
#ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
length: (size_t)length
block: (of_stream_async_read_block_t)block
{
ADD(OFRunLoop_ReadQueueItem, {
queueItem->buffer = buffer;
queueItem->length = length;
queueItem->block = [block copy];
})
}
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
exactLength: (size_t)exactLength
block: (of_stream_async_read_block_t)block
{
ADD(OFRunLoop_ExactReadQueueItem, {
queueItem->buffer = buffer;
queueItem->exactLength = exactLength;
queueItem->block = [block copy];
})
}
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
encoding: (of_string_encoding_t)encoding
block: (of_stream_async_read_line_block_t)block
{
ADD(OFRunLoop_ReadLineQueueItem, {
queueItem->encoding = encoding;
queueItem->block = [block copy];
})
}
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
block: (of_tcpsocket_async_accept_block_t)block
{
ADD(OFRunLoop_AcceptQueueItem, {
queueItem->block = [block copy];
})
}
#endif
#undef ADD
+ (void)OF_cancelAsyncRequestsForStream: (OFStream*)stream
{
void *pool = objc_autoreleasePoolPush();
OFRunLoop *runLoop = [self currentRunLoop];
OFList *queue;
if ((queue = [runLoop->readQueues objectForKey: stream]) != nil) {
assert([queue count] > 0);
[runLoop->streamObserver removeStreamForReading: stream];
[runLoop->readQueues removeObjectForKey: stream];
}
objc_autoreleasePoolPop(pool);
}
- init
{
self = [super init];
@try {
timersQueue = [[OFSortedList alloc] init];
#ifdef OF_HAVE_THREADS
timersQueueLock = [[OFMutex alloc] init];
#endif
streamObserver = [[OFStreamObserver alloc] init];
[streamObserver setDelegate: self];
readQueues = [[OFMutableDictionary alloc] init];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[timersQueue release];
#ifdef OF_HAVE_THREADS
[timersQueueLock release];
#endif
[streamObserver release];
[readQueues release];
[super dealloc];
}
- (void)addTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
[timersQueueLock lock];
@try {
#endif
[timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
} @finally {
[timersQueueLock unlock];
}
#endif
[timer OF_setInRunLoop: self];
[streamObserver cancel];
}
- (void)OF_removeTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
[timersQueueLock lock];
@try {
#endif
of_list_object_t *iter;
for (iter = [timersQueue firstListObject]; iter != NULL;
iter = iter->next) {
if ([iter->object isEqual: timer]) {
[timersQueue removeListObject: iter];
break;
}
}
#ifdef OF_HAVE_THREADS
} @finally {
[timersQueueLock unlock];
}
#endif
}
- (void)streamIsReadyForReading: (OFStream*)stream
{
OFList *queue = [readQueues objectForKey: stream];
of_list_object_t *listObject;
OF_ENSURE(queue != nil);
listObject = [queue firstListObject];
if ([listObject->object isKindOfClass:
[OFRunLoop_ReadQueueItem class]]) {
OFRunLoop_ReadQueueItem *queueItem = listObject->object;
size_t length;
OFException *exception = nil;
@try {
length = [stream readIntoBuffer: queueItem->buffer
length: queueItem->length];
} @catch (OFException *e) {
length = 0;
exception = e;
}
#ifdef OF_HAVE_BLOCKS
if (queueItem->block != NULL) {
if (!queueItem->block(stream, queueItem->buffer,
length, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading: stream];
[readQueues removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, void*, size_t,
OFException*) = (BOOL(*)(id, SEL, OFStream*, void*,
size_t, OFException*))
[queueItem->target methodForSelector:
queueItem->selector];
if (!func(queueItem->target, queueItem->selector,
stream, queueItem->buffer, length, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading: stream];
[readQueues removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
} else if ([listObject->object isKindOfClass:
[OFRunLoop_ExactReadQueueItem class]]) {
OFRunLoop_ExactReadQueueItem *queueItem = listObject->object;
size_t length;
OFException *exception = nil;
@try {
length = [stream
readIntoBuffer: (char*)queueItem->buffer +
queueItem->readLength
length: queueItem->exactLength -
queueItem->readLength];
} @catch (OFException *e) {
length = 0;
exception = e;
}
queueItem->readLength += length;
if (queueItem->readLength == queueItem->exactLength ||
[stream isAtEndOfStream] || exception != nil) {
#ifdef OF_HAVE_BLOCKS
if (queueItem->block != NULL) {
if (queueItem->block(stream, queueItem->buffer,
queueItem->readLength, exception))
queueItem->readLength = 0;
else {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading:
stream];
[readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, void*,
size_t, OFException*) = (BOOL(*)(id, SEL,
OFStream*, void*, size_t, OFException*))
[queueItem->target
methodForSelector: queueItem->selector];
if (func(queueItem->target,
queueItem->selector, stream,
queueItem->buffer, queueItem->readLength,
exception))
queueItem->readLength = 0;
else {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading:
stream];
[readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
}
} else if ([listObject->object isKindOfClass:
[OFRunLoop_ReadLineQueueItem class]]) {
OFRunLoop_ReadLineQueueItem *queueItem = listObject->object;
OFString *line;
OFException *exception = nil;
@try {
line = [stream
tryReadLineWithEncoding: queueItem->encoding];
} @catch (OFException *e) {
line = nil;
exception = e;
}
if (line != nil || [stream isAtEndOfStream] ||
exception != nil) {
#ifdef OF_HAVE_BLOCKS
if (queueItem->block != NULL) {
if (!queueItem->block(stream, line,
exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading:
stream];
[readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, OFString*,
OFException*) = (BOOL(*)(id, SEL, OFStream*,
OFString*, OFException*))
[queueItem->target methodForSelector:
queueItem->selector];
if (!func(queueItem->target,
queueItem->selector, stream, line,
exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading:
stream];
[readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
}
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
>
|
|
>
|
|
<
>
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
|
{
mainRunLoop = [runLoop retain];
}
#define ADD(type, code) \
void *pool = objc_autoreleasePoolPush(); \
OFRunLoop *runLoop = [self currentRunLoop]; \
OFList *queue = [runLoop->_readQueues objectForKey: stream]; \
type *queueItem; \
\
if (queue == nil) { \
queue = [OFList list]; \
[runLoop->_readQueues setObject: queue \
forKey: stream]; \
} \
\
if ([queue count] == 0) \
[runLoop->_streamObserver addStreamForReading: stream]; \
\
queueItem = [[[type alloc] init] autorelease]; \
code \
[queue appendObject: queueItem]; \
\
objc_autoreleasePoolPop(pool);
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
length: (size_t)length
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ReadQueueItem, {
queueItem->_target = [target retain];
queueItem->_selector = selector;
queueItem->_buffer = buffer;
queueItem->_length = length;
})
}
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
exactLength: (size_t)exactLength
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ExactReadQueueItem, {
queueItem->_target = [target retain];
queueItem->_selector = selector;
queueItem->_buffer = buffer;
queueItem->_exactLength = exactLength;
})
}
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
encoding: (of_string_encoding_t)encoding
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_ReadLineQueueItem, {
queueItem->_target = [target retain];
queueItem->_selector = selector;
queueItem->_encoding = encoding;
})
}
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
target: (id)target
selector: (SEL)selector
{
ADD(OFRunLoop_AcceptQueueItem, {
queueItem->_target = [target retain];
queueItem->_selector = selector;
})
}
#ifdef OF_HAVE_BLOCKS
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
length: (size_t)length
block: (of_stream_async_read_block_t)block
{
ADD(OFRunLoop_ReadQueueItem, {
queueItem->_block = [block copy];
queueItem->_buffer = buffer;
queueItem->_length = length;
})
}
+ (void)OF_addAsyncReadForStream: (OFStream*)stream
buffer: (void*)buffer
exactLength: (size_t)exactLength
block: (of_stream_async_read_block_t)block
{
ADD(OFRunLoop_ExactReadQueueItem, {
queueItem->_block = [block copy];
queueItem->_buffer = buffer;
queueItem->_exactLength = exactLength;
})
}
+ (void)OF_addAsyncReadLineForStream: (OFStream*)stream
encoding: (of_string_encoding_t)encoding
block: (of_stream_async_read_line_block_t)block
{
ADD(OFRunLoop_ReadLineQueueItem, {
queueItem->_block = [block copy];
queueItem->_encoding = encoding;
})
}
+ (void)OF_addAsyncAcceptForTCPSocket: (OFTCPSocket*)stream
block: (of_tcpsocket_async_accept_block_t)block
{
ADD(OFRunLoop_AcceptQueueItem, {
queueItem->_block = [block copy];
})
}
#endif
#undef ADD
+ (void)OF_cancelAsyncRequestsForStream: (OFStream*)stream
{
void *pool = objc_autoreleasePoolPush();
OFRunLoop *runLoop = [self currentRunLoop];
OFList *queue;
if ((queue = [runLoop->_readQueues objectForKey: stream]) != nil) {
assert([queue count] > 0);
[runLoop->_streamObserver removeStreamForReading: stream];
[runLoop->_readQueues removeObjectForKey: stream];
}
objc_autoreleasePoolPop(pool);
}
- init
{
self = [super init];
@try {
_timersQueue = [[OFSortedList alloc] init];
#ifdef OF_HAVE_THREADS
_timersQueueLock = [[OFMutex alloc] init];
#endif
_streamObserver = [[OFStreamObserver alloc] init];
[_streamObserver setDelegate: self];
_readQueues = [[OFMutableDictionary alloc] init];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_timersQueue release];
#ifdef OF_HAVE_THREADS
[_timersQueueLock release];
#endif
[_streamObserver release];
[_readQueues release];
[super dealloc];
}
- (void)addTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
[_timersQueueLock lock];
@try {
#endif
[_timersQueue insertObject: timer];
#ifdef OF_HAVE_THREADS
} @finally {
[_timersQueueLock unlock];
}
#endif
[timer OF_setInRunLoop: self];
[_streamObserver cancel];
}
- (void)OF_removeTimer: (OFTimer*)timer
{
#ifdef OF_HAVE_THREADS
[_timersQueueLock lock];
@try {
#endif
of_list_object_t *iter;
for (iter = [_timersQueue firstListObject]; iter != NULL;
iter = iter->next) {
if ([iter->object isEqual: timer]) {
[_timersQueue removeListObject: iter];
break;
}
}
#ifdef OF_HAVE_THREADS
} @finally {
[_timersQueueLock unlock];
}
#endif
}
- (void)streamIsReadyForReading: (OFStream*)stream
{
OFList *queue = [_readQueues objectForKey: stream];
of_list_object_t *listObject;
OF_ENSURE(queue != nil);
listObject = [queue firstListObject];
if ([listObject->object isKindOfClass:
[OFRunLoop_ReadQueueItem class]]) {
OFRunLoop_ReadQueueItem *queueItem = listObject->object;
size_t length;
OFException *exception = nil;
@try {
length = [stream readIntoBuffer: queueItem->_buffer
length: queueItem->_length];
} @catch (OFException *e) {
length = 0;
exception = e;
}
#ifdef OF_HAVE_BLOCKS
if (queueItem->_block != NULL) {
if (!queueItem->_block(stream, queueItem->_buffer,
length, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading: stream];
[_readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, void*, size_t,
OFException*) = (BOOL(*)(id, SEL, OFStream*, void*,
size_t, OFException*))
[queueItem->_target methodForSelector:
queueItem->_selector];
if (!func(queueItem->_target, queueItem->_selector,
stream, queueItem->_buffer, length, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading: stream];
[_readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
} else if ([listObject->object isKindOfClass:
[OFRunLoop_ExactReadQueueItem class]]) {
OFRunLoop_ExactReadQueueItem *queueItem = listObject->object;
size_t length;
OFException *exception = nil;
@try {
length = [stream
readIntoBuffer: (char*)queueItem->_buffer +
queueItem->_readLength
length: queueItem->_exactLength -
queueItem->_readLength];
} @catch (OFException *e) {
length = 0;
exception = e;
}
queueItem->_readLength += length;
if (queueItem->_readLength == queueItem->_exactLength ||
[stream isAtEndOfStream] || exception != nil) {
#ifdef OF_HAVE_BLOCKS
if (queueItem->_block != NULL) {
if (queueItem->_block(stream,
queueItem->_buffer, queueItem->_readLength,
exception))
queueItem->_readLength = 0;
else {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading:
stream];
[_readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, void*,
size_t, OFException*) = (BOOL(*)(id, SEL,
OFStream*, void*, size_t, OFException*))
[queueItem->_target
methodForSelector: queueItem->_selector];
if (func(queueItem->_target,
queueItem->_selector, stream,
queueItem->_buffer, queueItem->_readLength,
exception))
queueItem->_readLength = 0;
else {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading:
stream];
[_readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
}
} else if ([listObject->object isKindOfClass:
[OFRunLoop_ReadLineQueueItem class]]) {
OFRunLoop_ReadLineQueueItem *queueItem = listObject->object;
OFString *line;
OFException *exception = nil;
@try {
line = [stream
tryReadLineWithEncoding: queueItem->_encoding];
} @catch (OFException *e) {
line = nil;
exception = e;
}
if (line != nil || [stream isAtEndOfStream] ||
exception != nil) {
#ifdef OF_HAVE_BLOCKS
if (queueItem->_block != NULL) {
if (!queueItem->_block(stream, line,
exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading:
stream];
[_readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFStream*, OFString*,
OFException*) = (BOOL(*)(id, SEL, OFStream*,
OFString*, OFException*))
[queueItem->_target methodForSelector:
queueItem->_selector];
if (!func(queueItem->_target,
queueItem->_selector, stream, line,
exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading:
stream];
[_readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
}
|
︙ | | | ︙ | |
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
|
newSocket = [(OFTCPSocket*)stream accept];
} @catch (OFException *e) {
newSocket = nil;
exception = e;
}
#ifdef OF_HAVE_BLOCKS
if (queueItem->block != NULL) {
if (!queueItem->block((OFTCPSocket*)stream,
newSocket, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading: stream];
[readQueues removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
OFException*) =
(BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
OFException*))
[queueItem->target methodForSelector:
queueItem->selector];
if (!func(queueItem->target, queueItem->selector,
(OFTCPSocket*)stream, newSocket, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[streamObserver
removeStreamForReading: stream];
[readQueues removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
} else
OF_ENSURE(0);
}
- (void)run
{
running = YES;
while (running) {
void *pool = objc_autoreleasePoolPush();
OFDate *now = [OFDate date];
OFTimer *timer;
OFDate *nextTimer;
#ifdef OF_HAVE_THREADS
[timersQueueLock lock];
@try {
#endif
of_list_object_t *listObject =
[timersQueue firstListObject];
if (listObject != NULL &&
[[listObject->object fireDate] compare: now] !=
OF_ORDERED_DESCENDING) {
timer =
[[listObject->object retain] autorelease];
[timersQueue removeListObject: listObject];
[timer OF_setInRunLoop: nil];
} else
timer = nil;
#ifdef OF_HAVE_THREADS
} @finally {
[timersQueueLock unlock];
}
#endif
if ([timer isValid])
[timer fire];
#ifdef OF_HAVE_THREADS
[timersQueueLock lock];
@try {
#endif
nextTimer = [[timersQueue firstObject] fireDate];
#ifdef OF_HAVE_THREADS
} @finally {
[timersQueueLock unlock];
}
#endif
/* Watch for stream events until the next timer is due */
if (nextTimer != nil) {
double timeout = [nextTimer timeIntervalSinceNow];
if (timeout > 0)
[streamObserver observeWithTimeout: timeout];
} else {
/*
* No more timers: Just watch for streams until we get
* an event. If a timer is added by another thread, it
* cancels the observe.
*/
[streamObserver observe];
}
objc_autoreleasePoolPop(pool);
}
}
- (void)stop
{
running = NO;
[streamObserver cancel];
}
@end
|
|
|
|
>
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
|
newSocket = [(OFTCPSocket*)stream accept];
} @catch (OFException *e) {
newSocket = nil;
exception = e;
}
#ifdef OF_HAVE_BLOCKS
if (queueItem->_block != NULL) {
if (!queueItem->_block((OFTCPSocket*)stream,
newSocket, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading: stream];
[_readQueues
removeObjectForKey: stream];
}
}
} else {
#endif
BOOL (*func)(id, SEL, OFTCPSocket*, OFTCPSocket*,
OFException*) =
(BOOL(*)(id, SEL, OFTCPSocket*, OFTCPSocket*,
OFException*))
[queueItem->_target methodForSelector:
queueItem->_selector];
if (!func(queueItem->_target, queueItem->_selector,
(OFTCPSocket*)stream, newSocket, exception)) {
[queue removeListObject: listObject];
if ([queue count] == 0) {
[_streamObserver
removeStreamForReading: stream];
[_readQueues
removeObjectForKey: stream];
}
}
#ifdef OF_HAVE_BLOCKS
}
#endif
} else
OF_ENSURE(0);
}
- (void)run
{
_running = YES;
while (_running) {
void *pool = objc_autoreleasePoolPush();
OFDate *now = [OFDate date];
OFTimer *timer;
OFDate *nextTimer;
#ifdef OF_HAVE_THREADS
[_timersQueueLock lock];
@try {
#endif
of_list_object_t *listObject =
[_timersQueue firstListObject];
if (listObject != NULL &&
[[listObject->object fireDate] compare: now] !=
OF_ORDERED_DESCENDING) {
timer =
[[listObject->object retain] autorelease];
[_timersQueue removeListObject: listObject];
[timer OF_setInRunLoop: nil];
} else
timer = nil;
#ifdef OF_HAVE_THREADS
} @finally {
[_timersQueueLock unlock];
}
#endif
if ([timer isValid])
[timer fire];
#ifdef OF_HAVE_THREADS
[_timersQueueLock lock];
@try {
#endif
nextTimer = [[_timersQueue firstObject] fireDate];
#ifdef OF_HAVE_THREADS
} @finally {
[_timersQueueLock unlock];
}
#endif
/* Watch for stream events until the next timer is due */
if (nextTimer != nil) {
double timeout = [nextTimer timeIntervalSinceNow];
if (timeout > 0)
[_streamObserver observeWithTimeout: timeout];
} else {
/*
* No more timers: Just watch for streams until we get
* an event. If a timer is added by another thread, it
* cancels the observe.
*/
[_streamObserver observe];
}
objc_autoreleasePoolPop(pool);
}
}
- (void)stop
{
_running = NO;
[_streamObserver cancel];
}
@end
|
Modified src/OFSHA1Hash.h
from [acb4ce3d19]
to [0a2f6efcc5].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#define OF_SHA1_DIGEST_SIZE 20
/*!
* @brief A class which provides functions to create an SHA1 hash.
*/
@interface OFSHA1Hash: OFHash
{
uint32_t state[5];
uint64_t count;
char buffer[64];
uint8_t digest[OF_SHA1_DIGEST_SIZE];
}
@end
|
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#define OF_SHA1_DIGEST_SIZE 20
/*!
* @brief A class which provides functions to create an SHA1 hash.
*/
@interface OFSHA1Hash: OFHash
{
uint32_t _state[5];
uint64_t _count;
char _buffer[64];
uint8_t _digest[OF_SHA1_DIGEST_SIZE];
}
@end
|
Modified src/OFSHA1Hash.m
from [1e025da8be]
to [25afa6488f].
︙ | | | ︙ | |
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
return 64;
}
- init
{
self = [super init];
state[0] = 0x67452301;
state[1] = 0xEFCDAB89;
state[2] = 0x98BADCFE;
state[3] = 0x10325476;
state[4] = 0xC3D2E1F0;
return self;
}
- (void)updateWithBuffer: (const void*)buffer_
length: (size_t)length
{
if (length == 0)
return;
if (calculated)
@throw [OFHashAlreadyCalculatedException
exceptionWithClass: [self class]
hash: self];
sha1_update(state, &count, buffer, buffer_, length);
}
- (uint8_t*)digest
{
size_t i;
char finalcount[8];
if (calculated)
return digest;
for (i = 0; i < 8; i++)
/* Endian independent */
finalcount[i] = (char)((count >> ((7 - (i & 7)) * 8)) & 255);
sha1_update(state, &count, buffer, "\200", 1);
while ((count & 504) != 448)
sha1_update(state, &count, buffer, "\0", 1);
/* Should cause a sha1_transform() */
sha1_update(state, &count, buffer, finalcount, 8);
for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++)
digest[i] = (char)((state[i >> 2] >>
((3 - (i & 3)) * 8)) & 255);
calculated = YES;
return digest;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
return 64;
}
- init
{
self = [super init];
_state[0] = 0x67452301;
_state[1] = 0xEFCDAB89;
_state[2] = 0x98BADCFE;
_state[3] = 0x10325476;
_state[4] = 0xC3D2E1F0;
return self;
}
- (void)updateWithBuffer: (const void*)buffer
length: (size_t)length
{
if (length == 0)
return;
if (_calculated)
@throw [OFHashAlreadyCalculatedException
exceptionWithClass: [self class]
hash: self];
sha1_update(_state, &_count, _buffer, buffer, length);
}
- (uint8_t*)digest
{
size_t i;
char finalcount[8];
if (_calculated)
return _digest;
for (i = 0; i < 8; i++)
/* Endian independent */
finalcount[i] = (char)((_count >> ((7 - (i & 7)) * 8)) & 255);
sha1_update(_state, &_count, _buffer, "\200", 1);
while ((_count & 504) != 448)
sha1_update(_state, &_count, _buffer, "\0", 1);
/* Should cause a sha1_transform() */
sha1_update(_state, &_count, _buffer, finalcount, 8);
for (i = 0; i < OF_SHA1_DIGEST_SIZE; i++)
_digest[i] = (char)((_state[i >> 2] >>
((3 - (i & 3)) * 8)) & 255);
_calculated = YES;
return _digest;
}
@end
|
Modified src/OFSeekableStream.m
from [52f33aa767]
to [b3e35f31cf].
︙ | | | ︙ | |
30
31
32
33
34
35
36
37
38
39
40
41
|
- (void)seekToOffset: (off_t)offset
whence: (int)whence
{
[self lowlevelSeekToOffset: offset
whence: whence];
[self freeMemory: cache];
cache = NULL;
cacheLength = 0;
}
@end
|
|
|
|
|
30
31
32
33
34
35
36
37
38
39
40
41
|
- (void)seekToOffset: (off_t)offset
whence: (int)whence
{
[self lowlevelSeekToOffset: offset
whence: whence];
[self freeMemory: _cache];
_cache = NULL;
_cacheLength = 0;
}
@end
|
Modified src/OFSet_hashtable.h
from [d95c52fb45]
to [74dd4b8396].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFSet.h"
@class OFMapTable;
@interface OFSet_hashtable: OFSet
{
OFMapTable *mapTable;
}
- initWithCapacity: (size_t)capacity;
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFSet.h"
@class OFMapTable;
@interface OFSet_hashtable: OFSet
{
OFMapTable *_mapTable;
}
- initWithCapacity: (size_t)capacity;
@end
|
Modified src/OFSet_hashtable.m
from [3deaa65aa1]
to [86943d9b76].
︙ | | | ︙ | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
}
- initWithCapacity: (size_t)capacity
{
self = [super init];
@try {
mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: capacity];
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
}
- initWithCapacity: (size_t)capacity
{
self = [super init];
@try {
_mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: capacity];
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
@try {
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator;
id object;
enumerator = [set objectEnumerator];
while ((object = [enumerator nextObject]) != nil)
[mapTable setValue: (void*)1
forKey: object];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
@try {
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator;
id object;
enumerator = [set objectEnumerator];
while ((object = [enumerator nextObject]) != nil)
[_mapTable setValue: (void*)1
forKey: object];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
@try {
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator;
id object;
enumerator = [array objectEnumerator];
while ((object = [enumerator nextObject]) != nil)
[mapTable setValue: (void*)1
forKey: object];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObjects: (id const*)objects
count: (size_t)count
{
self = [self initWithCapacity: count];
@try {
size_t i;
for (i = 0; i < count; i++)
[mapTable setValue: (void*)1
forKey: objects[i]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
@try {
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator;
id object;
enumerator = [array objectEnumerator];
while ((object = [enumerator nextObject]) != nil)
[_mapTable setValue: (void*)1
forKey: object];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithObjects: (id const*)objects
count: (size_t)count
{
self = [self initWithCapacity: count];
@try {
size_t i;
for (i = 0; i < count; i++)
[_mapTable setValue: (void*)1
forKey: objects[i]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
va_list argumentsCopy;
size_t count;
va_copy(argumentsCopy, arguments);
for (count = 1; va_arg(argumentsCopy, id) != nil; count++);
mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: count];
[mapTable setValue: (void*)1
forKey: firstObject];
while ((object = va_arg(arguments, id)) != nil)
[mapTable setValue: (void*)1
forKey: object];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
va_list argumentsCopy;
size_t count;
va_copy(argumentsCopy, arguments);
for (count = 1; va_arg(argumentsCopy, id) != nil; count++);
_mapTable = [[OFMapTable alloc]
initWithKeyFunctions: keyFunctions
valueFunctions: valueFunctions
capacity: count];
[_mapTable setValue: (void*)1
forKey: firstObject];
while ((object = va_arg(arguments, id)) != nil)
[_mapTable setValue: (void*)1
forKey: object];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
selector: _cmd];
enumerator = [[element elementsForNamespace:
OF_SERIALIZATION_NS] objectEnumerator];
while ((child = [enumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
[mapTable setValue: (void*)1
forKey: [child objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[mapTable release];
[super dealloc];
}
- (size_t)count
{
return [mapTable count];
}
- (BOOL)containsObject: (id)object
{
if (object == nil)
return NO;
return ([mapTable valueForKey: object] != nil);
}
- (BOOL)isEqual: (id)object
{
OFSet_hashtable *otherSet;
if (![object isKindOfClass: [OFSet_hashtable class]] &&
![object isKindOfClass: [OFMutableSet_hashtable class]] &&
![object isKindOfClass: [OFCountedSet_hashtable class]])
return [super isEqual: object];
otherSet = object;
return [otherSet->mapTable isEqual: mapTable];
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [mapTable keyEnumerator]
object: self] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count
{
return [mapTable countByEnumeratingWithState: state
objects: objects
count: count];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block
{
@try {
[mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
selector: _cmd];
enumerator = [[element elementsForNamespace:
OF_SERIALIZATION_NS] objectEnumerator];
while ((child = [enumerator nextObject]) != nil) {
void *pool2 = objc_autoreleasePoolPush();
[_mapTable setValue: (void*)1
forKey: [child objectByDeserializing]];
objc_autoreleasePoolPop(pool2);
}
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_mapTable release];
[super dealloc];
}
- (size_t)count
{
return [_mapTable count];
}
- (BOOL)containsObject: (id)object
{
if (object == nil)
return NO;
return ([_mapTable valueForKey: object] != nil);
}
- (BOOL)isEqual: (id)object
{
OFSet_hashtable *set;
if (![object isKindOfClass: [OFSet_hashtable class]] &&
![object isKindOfClass: [OFMutableSet_hashtable class]] &&
![object isKindOfClass: [OFCountedSet_hashtable class]])
return [super isEqual: object];
set = object;
return [set->_mapTable isEqual: _mapTable];
}
- (OFEnumerator*)objectEnumerator
{
return [[[OFMapTableEnumeratorWrapper alloc]
initWithEnumerator: [_mapTable keyEnumerator]
object: self] autorelease];
}
- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state
objects: (id*)objects
count: (int)count
{
return [_mapTable countByEnumeratingWithState: state
objects: objects
count: count];
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateObjectsUsingBlock: (of_set_enumeration_block_t)block
{
@try {
[_mapTable enumerateKeysAndValuesUsingBlock:
^ (void *key, void *value, BOOL *stop) {
block(key, stop);
}];
} @catch (OFEnumerationMutationException *e) {
@throw [OFEnumerationMutationException
exceptionWithClass: [self class]
object: self];
}
}
#endif
@end
|
Modified src/OFSortedList.m
from [153621bbfc]
to [0d00948527].
︙ | | | ︙ | |
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
abort();
}
- (of_list_object_t*)insertObject: (id <OFComparing>)object
{
of_list_object_t *iter;
for (iter = lastListObject; iter != NULL; iter = iter->previous) {
if ([object compare: iter->object] != OF_ORDERED_ASCENDING)
return [super insertObject: object
afterListObject: iter];
}
return [super prependObject: object];
}
@end
|
|
|
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
abort();
}
- (of_list_object_t*)insertObject: (id <OFComparing>)object
{
of_list_object_t *iter;
for (iter = _lastListObject; iter != NULL; iter = iter->previous) {
if ([object compare: iter->object] != OF_ORDERED_ASCENDING)
return [super insertObject: object
afterListObject: iter];
}
return [super prependObject: object];
}
@end
|
Modified src/OFStream.h
from [6b4f15f3b1]
to [57e418e361].
︙ | | | ︙ | |
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
* the methods that do the actual work. OFStream uses those for all other
* methods and does all the caching and other stuff for you. If you
* override these methods without the lowlevel prefix, you *will* break
* caching and get broken results!
*/
@interface OFStream: OFObject <OFCopying>
{
char *cache;
char *writeBuffer;
size_t cacheLength, writeBufferLength;
BOOL writeBufferEnabled;
BOOL blocking, waitingForDelimiter;
}
#ifdef OF_HAVE_PROPERTIES
@property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled;
@property (getter=isBlocking) BOOL blocking;
@property (readonly, getter=isAtEndOfStream) BOOL atEndOfStream;
#endif
|
|
|
|
|
|
|
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
* the methods that do the actual work. OFStream uses those for all other
* methods and does all the caching and other stuff for you. If you
* override these methods without the lowlevel prefix, you *will* break
* caching and get broken results!
*/
@interface OFStream: OFObject <OFCopying>
{
char *_cache;
char *_writeBuffer;
size_t _cacheLength, _writeBufferLength;
BOOL _writeBufferEnabled;
BOOL _blocking, _waitingForDelimiter;
}
#ifdef OF_HAVE_PROPERTIES
@property (getter=isWriteBufferEnabled) BOOL writeBufferEnabled;
@property (getter=isBlocking) BOOL blocking;
@property (readonly, getter=isAtEndOfStream) BOOL atEndOfStream;
#endif
|
︙ | | | ︙ | |
Modified src/OFStream.m
from [3a3eebc79f]
to [0bbf55df10].
︙ | | | ︙ | |
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
[self release];
@throw e;
}
}
self = [super init];
cache = NULL;
writeBuffer = NULL;
blocking = YES;
return self;
}
- (BOOL)lowlevelIsAtEndOfStream
{
[self doesNotRecognizeSelector: _cmd];
|
<
<
|
|
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
[self release];
@throw e;
}
}
self = [super init];
_blocking = YES;
return self;
}
- (BOOL)lowlevelIsAtEndOfStream
{
[self doesNotRecognizeSelector: _cmd];
|
︙ | | | ︙ | |
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
- copy
{
return [self retain];
}
- (BOOL)isAtEndOfStream
{
if (cacheLength > 0)
return NO;
return [self lowlevelIsAtEndOfStream];
}
- (size_t)readIntoBuffer: (void*)buffer
length: (size_t)length
{
if (cacheLength == 0)
return [self lowlevelReadIntoBuffer: buffer
length: length];
if (length >= cacheLength) {
size_t ret = cacheLength;
memcpy(buffer, cache, cacheLength);
[self freeMemory: cache];
cache = NULL;
cacheLength = 0;
return ret;
} else {
char *tmp = [self allocMemoryWithSize: cacheLength - length];
memcpy(tmp, cache + length, cacheLength - length);
memcpy(buffer, cache, length);
[self freeMemory: cache];
cache = tmp;
cacheLength -= length;
return length;
}
}
- (void)readIntoBuffer: (void*)buffer
exactLength: (size_t)length
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
- copy
{
return [self retain];
}
- (BOOL)isAtEndOfStream
{
if (_cacheLength > 0)
return NO;
return [self lowlevelIsAtEndOfStream];
}
- (size_t)readIntoBuffer: (void*)buffer
length: (size_t)length
{
if (_cacheLength == 0)
return [self lowlevelReadIntoBuffer: buffer
length: length];
if (length >= _cacheLength) {
size_t ret = _cacheLength;
memcpy(buffer, _cache, _cacheLength);
[self freeMemory: _cache];
_cache = NULL;
_cacheLength = 0;
return ret;
} else {
char *tmp = [self allocMemoryWithSize: _cacheLength - length];
memcpy(tmp, _cache + length, _cacheLength - length);
memcpy(buffer, _cache, length);
[self freeMemory: _cache];
_cache = tmp;
_cacheLength -= length;
return length;
}
}
- (void)readIntoBuffer: (void*)buffer
exactLength: (size_t)length
|
︙ | | | ︙ | |
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
|
- (OFString*)tryReadLineWithEncoding: (of_string_encoding_t)encoding
{
size_t i, pageSize, bufferLength, retLength;
char *retCString, *buffer, *newCache;
OFString *ret;
/* Look if there's a line or \0 in our cache */
if (!waitingForDelimiter && cache != NULL) {
for (i = 0; i < cacheLength; i++) {
if OF_UNLIKELY (cache[i] == '\n' || cache[i] == '\0') {
retLength = i;
if (i > 0 && cache[i - 1] == '\r')
retLength--;
ret = [OFString stringWithCString: cache
encoding: encoding
length: retLength];
newCache = [self
allocMemoryWithSize: cacheLength - i - 1];
if (newCache != NULL)
memcpy(newCache, cache + i + 1,
cacheLength - i - 1);
[self freeMemory: cache];
cache = newCache;
cacheLength -= i + 1;
waitingForDelimiter = NO;
return ret;
}
}
}
/* Read and see if we got a newline or \0 */
pageSize = [OFSystemInfo pageSize];
buffer = [self allocMemoryWithSize: pageSize];
@try {
if ([self lowlevelIsAtEndOfStream]) {
if (cache == NULL) {
waitingForDelimiter = NO;
return nil;
}
retLength = cacheLength;
if (retLength > 0 && cache[retLength - 1] == '\r')
retLength--;
ret = [OFString stringWithCString: cache
encoding: encoding
length: retLength];
[self freeMemory: cache];
cache = NULL;
cacheLength = 0;
waitingForDelimiter = NO;
return ret;
}
bufferLength = [self lowlevelReadIntoBuffer: buffer
length: pageSize];
/* Look if there's a newline or \0 */
for (i = 0; i < bufferLength; i++) {
if OF_UNLIKELY (buffer[i] == '\n' ||
buffer[i] == '\0') {
retLength = cacheLength + i;
retCString = [self
allocMemoryWithSize: retLength];
if (cache != NULL)
memcpy(retCString, cache, cacheLength);
memcpy(retCString + cacheLength, buffer, i);
if (retLength > 0 &&
retCString[retLength - 1] == '\r')
retLength--;
@try {
char *rcs = retCString;
size_t rl = retLength;
ret = [OFString
stringWithCString: rcs
encoding: encoding
length: rl];
} @catch (id e) {
/*
* Append data to cache to prevent loss
* of data due to wrong encoding.
*/
cache = [self
resizeMemory: cache
size: cacheLength +
bufferLength];
if (cache != NULL)
memcpy(cache + cacheLength,
buffer, bufferLength);
cacheLength += bufferLength;
@throw e;
} @finally {
[self freeMemory: retCString];
}
newCache = [self allocMemoryWithSize:
bufferLength - i - 1];
if (newCache != NULL)
memcpy(newCache, buffer + i + 1,
bufferLength - i - 1);
[self freeMemory: cache];
cache = newCache;
cacheLength = bufferLength - i - 1;
waitingForDelimiter = NO;
return ret;
}
}
/* There was no newline or \0 */
cache = [self resizeMemory: cache
size: cacheLength + bufferLength];
/*
* It's possible that cacheLen + len is 0 and thus cache was
* set to NULL by resizeMemory:size:.
*/
if (cache != NULL)
memcpy(cache + cacheLength, buffer, bufferLength);
cacheLength += bufferLength;
} @finally {
[self freeMemory: buffer];
}
waitingForDelimiter = YES;
return nil;
}
- (OFString*)readLine
{
return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
|
- (OFString*)tryReadLineWithEncoding: (of_string_encoding_t)encoding
{
size_t i, pageSize, bufferLength, retLength;
char *retCString, *buffer, *newCache;
OFString *ret;
/* Look if there's a line or \0 in our cache */
if (!_waitingForDelimiter && _cache != NULL) {
for (i = 0; i < _cacheLength; i++) {
if OF_UNLIKELY (_cache[i] == '\n' ||
_cache[i] == '\0') {
retLength = i;
if (i > 0 && _cache[i - 1] == '\r')
retLength--;
ret = [OFString stringWithCString: _cache
encoding: encoding
length: retLength];
newCache = [self
allocMemoryWithSize: _cacheLength - i - 1];
if (newCache != NULL)
memcpy(newCache, _cache + i + 1,
_cacheLength - i - 1);
[self freeMemory: _cache];
_cache = newCache;
_cacheLength -= i + 1;
_waitingForDelimiter = NO;
return ret;
}
}
}
/* Read and see if we got a newline or \0 */
pageSize = [OFSystemInfo pageSize];
buffer = [self allocMemoryWithSize: pageSize];
@try {
if ([self lowlevelIsAtEndOfStream]) {
if (_cache == NULL) {
_waitingForDelimiter = NO;
return nil;
}
retLength = _cacheLength;
if (retLength > 0 && _cache[retLength - 1] == '\r')
retLength--;
ret = [OFString stringWithCString: _cache
encoding: encoding
length: retLength];
[self freeMemory: _cache];
_cache = NULL;
_cacheLength = 0;
_waitingForDelimiter = NO;
return ret;
}
bufferLength = [self lowlevelReadIntoBuffer: buffer
length: pageSize];
/* Look if there's a newline or \0 */
for (i = 0; i < bufferLength; i++) {
if OF_UNLIKELY (buffer[i] == '\n' ||
buffer[i] == '\0') {
retLength = _cacheLength + i;
retCString = [self
allocMemoryWithSize: retLength];
if (_cache != NULL)
memcpy(retCString, _cache,
_cacheLength);
memcpy(retCString + _cacheLength, buffer, i);
if (retLength > 0 &&
retCString[retLength - 1] == '\r')
retLength--;
@try {
char *rcs = retCString;
size_t rl = retLength;
ret = [OFString
stringWithCString: rcs
encoding: encoding
length: rl];
} @catch (id e) {
/*
* Append data to cache to prevent loss
* of data due to wrong encoding.
*/
_cache = [self
resizeMemory: _cache
size: _cacheLength +
bufferLength];
if (_cache != NULL)
memcpy(_cache + _cacheLength,
buffer, bufferLength);
_cacheLength += bufferLength;
@throw e;
} @finally {
[self freeMemory: retCString];
}
newCache = [self allocMemoryWithSize:
bufferLength - i - 1];
if (newCache != NULL)
memcpy(newCache, buffer + i + 1,
bufferLength - i - 1);
[self freeMemory: _cache];
_cache = newCache;
_cacheLength = bufferLength - i - 1;
_waitingForDelimiter = NO;
return ret;
}
}
/* There was no newline or \0 */
_cache = [self resizeMemory: _cache
size: _cacheLength + bufferLength];
/*
* It's possible that _cacheLength + bufferLength is 0 and thus
* _cache was set to NULL by resizeMemory:size:.
*/
if (_cache != NULL)
memcpy(_cache + _cacheLength, buffer, bufferLength);
_cacheLength += bufferLength;
} @finally {
[self freeMemory: buffer];
}
_waitingForDelimiter = YES;
return nil;
}
- (OFString*)readLine
{
return [self readLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}
|
︙ | | | ︙ | |
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
|
if (delimiterLength == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
/* Look if there's something in our cache */
if (!waitingForDelimiter && cache != NULL) {
for (i = 0; i < cacheLength; i++) {
if (cache[i] != delimiterCString[j++])
j = 0;
if (j == delimiterLength || cache[i] == '\0') {
if (cache[i] == '\0')
delimiterLength = 1;
ret = [OFString
stringWithCString: cache
encoding: encoding
length: i + 1 - delimiterLength];
newCache = [self allocMemoryWithSize:
cacheLength - i - 1];
if (newCache != NULL)
memcpy(newCache, cache + i + 1,
cacheLength - i - 1);
[self freeMemory: cache];
cache = newCache;
cacheLength -= i + 1;
waitingForDelimiter = NO;
return ret;
}
}
}
/* Read and see if we got a delimiter or \0 */
pageSize = [OFSystemInfo pageSize];
buffer = [self allocMemoryWithSize: pageSize];
@try {
if ([self lowlevelIsAtEndOfStream]) {
if (cache == NULL) {
waitingForDelimiter = NO;
return nil;
}
ret = [OFString stringWithCString: cache
encoding: encoding
length: cacheLength];
[self freeMemory: cache];
cache = NULL;
cacheLength = 0;
waitingForDelimiter = NO;
return ret;
}
bufferLength = [self lowlevelReadIntoBuffer: buffer
length: pageSize];
/* Look if there's a delimiter or \0 */
for (i = 0; i < bufferLength; i++) {
if (buffer[i] != delimiterCString[j++])
j = 0;
if (j == delimiterLength || buffer[i] == '\0') {
if (buffer[i] == '\0')
delimiterLength = 1;
retLength = cacheLength + i + 1 -
delimiterLength;
retCString = [self
allocMemoryWithSize: retLength];
if (cache != NULL && cacheLength <= retLength)
memcpy(retCString, cache, cacheLength);
else if (cache != NULL)
memcpy(retCString, cache, retLength);
if (i >= delimiterLength)
memcpy(retCString + cacheLength,
buffer, i + 1 - delimiterLength);
@try {
char *rcs = retCString;
size_t rl = retLength;
ret = [OFString
stringWithCString: rcs
encoding: encoding
length: rl];
} @finally {
[self freeMemory: retCString];
}
newCache = [self allocMemoryWithSize:
bufferLength - i - 1];
if (newCache != NULL)
memcpy(newCache, buffer + i + 1,
bufferLength - i - 1);
[self freeMemory: cache];
cache = newCache;
cacheLength = bufferLength - i - 1;
waitingForDelimiter = NO;
return ret;
}
}
/* Neither the delimiter nor \0 was found */
cache = [self resizeMemory: cache
size: cacheLength + bufferLength];
/*
* It's possible that cacheLen + len is 0 and thus cache was
* set to NULL by resizeMemory:size:.
*/
if (cache != NULL)
memcpy(cache + cacheLength, buffer,
bufferLength);
cacheLength += bufferLength;
} @finally {
[self freeMemory: buffer];
}
waitingForDelimiter = YES;
return nil;
}
- (OFString*)readTillDelimiter: (OFString*)delimiter
{
return [self readTillDelimiter: delimiter
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
|
if (delimiterLength == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
/* Look if there's something in our cache */
if (!_waitingForDelimiter && _cache != NULL) {
for (i = 0; i < _cacheLength; i++) {
if (_cache[i] != delimiterCString[j++])
j = 0;
if (j == delimiterLength || _cache[i] == '\0') {
if (_cache[i] == '\0')
delimiterLength = 1;
ret = [OFString
stringWithCString: _cache
encoding: encoding
length: i + 1 - delimiterLength];
newCache = [self allocMemoryWithSize:
_cacheLength - i - 1];
if (newCache != NULL)
memcpy(newCache, _cache + i + 1,
_cacheLength - i - 1);
[self freeMemory: _cache];
_cache = newCache;
_cacheLength -= i + 1;
_waitingForDelimiter = NO;
return ret;
}
}
}
/* Read and see if we got a delimiter or \0 */
pageSize = [OFSystemInfo pageSize];
buffer = [self allocMemoryWithSize: pageSize];
@try {
if ([self lowlevelIsAtEndOfStream]) {
if (_cache == NULL) {
_waitingForDelimiter = NO;
return nil;
}
ret = [OFString stringWithCString: _cache
encoding: encoding
length: _cacheLength];
[self freeMemory: _cache];
_cache = NULL;
_cacheLength = 0;
_waitingForDelimiter = NO;
return ret;
}
bufferLength = [self lowlevelReadIntoBuffer: buffer
length: pageSize];
/* Look if there's a delimiter or \0 */
for (i = 0; i < bufferLength; i++) {
if (buffer[i] != delimiterCString[j++])
j = 0;
if (j == delimiterLength || buffer[i] == '\0') {
if (buffer[i] == '\0')
delimiterLength = 1;
retLength = _cacheLength + i + 1 -
delimiterLength;
retCString = [self
allocMemoryWithSize: retLength];
if (_cache != NULL && _cacheLength <= retLength)
memcpy(retCString, _cache,
_cacheLength);
else if (_cache != NULL)
memcpy(retCString, _cache, retLength);
if (i >= delimiterLength)
memcpy(retCString + _cacheLength,
buffer, i + 1 - delimiterLength);
@try {
char *rcs = retCString;
size_t rl = retLength;
ret = [OFString
stringWithCString: rcs
encoding: encoding
length: rl];
} @finally {
[self freeMemory: retCString];
}
newCache = [self allocMemoryWithSize:
bufferLength - i - 1];
if (newCache != NULL)
memcpy(newCache, buffer + i + 1,
bufferLength - i - 1);
[self freeMemory: _cache];
_cache = newCache;
_cacheLength = bufferLength - i - 1;
_waitingForDelimiter = NO;
return ret;
}
}
/* Neither the delimiter nor \0 was found */
_cache = [self resizeMemory: _cache
size: _cacheLength + bufferLength];
/*
* It's possible that _cacheLength + bufferLength is 0 and thus
* _cache was set to NULL by resizeMemory:size:.
*/
if (_cache != NULL)
memcpy(_cache + _cacheLength, buffer, bufferLength);
_cacheLength += bufferLength;
} @finally {
[self freeMemory: buffer];
}
_waitingForDelimiter = YES;
return nil;
}
- (OFString*)readTillDelimiter: (OFString*)delimiter
{
return [self readTillDelimiter: delimiter
|
︙ | | | ︙ | |
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
|
{
return [self tryReadTillDelimiter: delimiter
encoding: OF_STRING_ENCODING_UTF_8];
}
- (BOOL)isWriteBufferEnabled
{
return writeBufferEnabled;
}
- (void)setWriteBufferEnabled: (BOOL)enable
{
writeBufferEnabled = enable;
}
- (void)flushWriteBuffer
{
if (writeBuffer == NULL)
return;
[self lowlevelWriteBuffer: writeBuffer
length: writeBufferLength];
[self freeMemory: writeBuffer];
writeBuffer = NULL;
writeBufferLength = 0;
}
- (void)writeBuffer: (const void*)buffer
length: (size_t)length
{
if (!writeBufferEnabled)
[self lowlevelWriteBuffer: buffer
length: length];
else {
writeBuffer = [self resizeMemory: writeBuffer
size: writeBufferLength + length];
memcpy(writeBuffer + writeBufferLength, buffer, length);
writeBufferLength += length;
}
}
- (void)writeInt8: (uint8_t)int8
{
[self writeBuffer: (char*)&int8
length: 1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
|
{
return [self tryReadTillDelimiter: delimiter
encoding: OF_STRING_ENCODING_UTF_8];
}
- (BOOL)isWriteBufferEnabled
{
return _writeBufferEnabled;
}
- (void)setWriteBufferEnabled: (BOOL)enable
{
_writeBufferEnabled = enable;
}
- (void)flushWriteBuffer
{
if (_writeBuffer == NULL)
return;
[self lowlevelWriteBuffer: _writeBuffer
length: _writeBufferLength];
[self freeMemory: _writeBuffer];
_writeBuffer = NULL;
_writeBufferLength = 0;
}
- (void)writeBuffer: (const void*)buffer
length: (size_t)length
{
if (!_writeBufferEnabled)
[self lowlevelWriteBuffer: buffer
length: length];
else {
_writeBuffer = [self resizeMemory: _writeBuffer
size: _writeBufferLength + length];
memcpy(_writeBuffer + _writeBufferLength, buffer, length);
_writeBufferLength += length;
}
}
- (void)writeInt8: (uint8_t)int8
{
[self writeBuffer: (char*)&int8
length: 1];
|
︙ | | | ︙ | |
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
|
}
return length;
}
- (size_t)pendingBytes
{
return cacheLength;
}
- (BOOL)isBlocking
{
return blocking;
}
- (void)setBlocking: (BOOL)enable
{
#ifndef _WIN32
BOOL readImplemented = NO, writeImplemented = NO;
|
|
|
|
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
|
}
return length;
}
- (size_t)pendingBytes
{
return _cacheLength;
}
- (BOOL)isBlocking
{
return _blocking;
}
- (void)setBlocking: (BOOL)enable
{
#ifndef _WIN32
BOOL readImplemented = NO, writeImplemented = NO;
|
︙ | | | ︙ | |
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
|
} @catch (OFNotImplementedException *e) {
}
if (!readImplemented && !writeImplemented)
@throw [OFNotImplementedException
exceptionWithClass: [self class]
selector: _cmd];
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (int)fileDescriptorForReading
|
>
>
|
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
|
} @catch (OFNotImplementedException *e) {
}
if (!readImplemented && !writeImplemented)
@throw [OFNotImplementedException
exceptionWithClass: [self class]
selector: _cmd];
_blocking = enable;
#else
[self doesNotRecognizeSelector: _cmd];
abort();
#endif
}
- (int)fileDescriptorForReading
|
︙ | | | ︙ | |
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
|
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (BOOL)OF_isWaitingForDelimiter
{
return waitingForDelimiter;
}
@end
|
|
|
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
|
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (BOOL)OF_isWaitingForDelimiter
{
return _waitingForDelimiter;
}
@end
|
Modified src/OFStreamObserver.h
from [b07d550270]
to [cdfadcf2ee].
︙ | | | ︙ | |
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
|
/*!
* @brief A class that can observe multiple streams at once.
*
* @note Currently, Win32 can only observe sockets and not files!
*/
@interface OFStreamObserver: OFObject
{
OFMutableArray *readStreams;
OFMutableArray *writeStreams;
__unsafe_unretained OFStream **FDToStream;
size_t maxFD;
OFMutableArray *queue;
OFDataArray *queueInfo, *queueFDs;
id <OFStreamObserverDelegate> delegate;
int cancelFD[2];
#ifdef _WIN32
struct sockaddr_in cancelAddr;
#endif
#ifdef OF_HAVE_THREADS
OFMutex *mutex;
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFStreamObserverDelegate> delegate;
#endif
|
|
|
|
|
|
|
|
|
|
|
|
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
|
/*!
* @brief A class that can observe multiple streams at once.
*
* @note Currently, Win32 can only observe sockets and not files!
*/
@interface OFStreamObserver: OFObject
{
OFMutableArray *_readStreams;
OFMutableArray *_writeStreams;
__unsafe_unretained OFStream **_FDToStream;
size_t _maxFD;
OFMutableArray *_queue;
OFDataArray *_queueInfo, *_queueFDs;
id <OFStreamObserverDelegate> _delegate;
int _cancelFD[2];
#ifdef _WIN32
struct sockaddr_in _cancelAddr;
#endif
#ifdef OF_HAVE_THREADS
OFMutex *_mutex;
#endif
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFStreamObserverDelegate> delegate;
#endif
|
︙ | | | ︙ | |
Modified src/OFStreamObserver.m
from [b6d33523f1]
to [67edca5fb3].
︙ | | | ︙ | |
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
@try {
#ifdef _WIN32
struct sockaddr_in cancelAddr2;
socklen_t cancelAddrLen;
#endif
readStreams = [[OFMutableArray alloc] init];
writeStreams = [[OFMutableArray alloc] init];
queue = [[OFMutableArray alloc] init];
queueInfo = [[OFDataArray alloc] initWithItemSize: sizeof(int)];
queueFDs = [[OFDataArray alloc] initWithItemSize: sizeof(int)];
#ifndef _WIN32
if (pipe(cancelFD))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
#else
/* Make sure WSAStartup has been called */
[OFTCPSocket class];
cancelFD[0] = socket(AF_INET, SOCK_DGRAM, 0);
cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0);
if (cancelFD[0] == INVALID_SOCKET ||
cancelFD[1] == INVALID_SOCKET)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
cancelAddr.sin_family = AF_INET;
cancelAddr.sin_port = 0;
cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
cancelAddr2 = cancelAddr;
if (bind(cancelFD[0], (struct sockaddr*)&cancelAddr,
sizeof(cancelAddr)) || bind(cancelFD[1],
(struct sockaddr*)&cancelAddr2, sizeof(cancelAddr2)))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
cancelAddrLen = sizeof(cancelAddr);
if (getsockname(cancelFD[0], (struct sockaddr*)&cancelAddr,
&cancelAddrLen))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
#endif
maxFD = cancelFD[0];
FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
count: maxFD + 1];
FDToStream[cancelFD[0]] = nil;
#ifdef OF_HAVE_THREADS
mutex = [[OFMutex alloc] init];
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
close(cancelFD[0]);
close(cancelFD[1]);
[readStreams release];
[writeStreams release];
[queue release];
[queueInfo release];
[queueFDs release];
#ifdef OF_HAVE_THREADS
[mutex release];
#endif
[super dealloc];
}
- (id <OFStreamObserverDelegate>)delegate
{
return delegate;
}
- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate_
{
delegate = delegate_;
}
- (void)addStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[mutex lock];
#endif
@try {
int qi = QUEUE_ADD | QUEUE_READ;
int fd = [stream fileDescriptorForReading];
[queue addObject: stream];
[queueInfo addItem: &qi];
[queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[mutex unlock];
#endif
}
[self cancel];
}
- (void)addStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[mutex lock];
#endif
@try {
int qi = QUEUE_ADD | QUEUE_WRITE;
int fd = [stream fileDescriptorForWriting];
[queue addObject: stream];
[queueInfo addItem: &qi];
[queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[mutex unlock];
#endif
}
[self cancel];
}
- (void)removeStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[mutex lock];
#endif
@try {
int qi = QUEUE_REMOVE | QUEUE_READ;
int fd = [stream fileDescriptorForReading];
[queue addObject: stream];
[queueInfo addItem: &qi];
[queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[mutex unlock];
#endif
}
#ifndef _WIN32
OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
sizeof(cancelAddr)) > 0);
#endif
}
- (void)removeStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[mutex lock];
#endif
@try {
int qi = QUEUE_REMOVE | QUEUE_WRITE;
int fd = [stream fileDescriptorForWriting];
[queue addObject: stream];
[queueInfo addItem: &qi];
[queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[mutex unlock];
#endif
}
#ifndef _WIN32
OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
sizeof(cancelAddr)) > 0);
#endif
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
|
<
|
|
|
|
|
<
<
<
<
|
<
|
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
@try {
#ifdef _WIN32
struct sockaddr_in cancelAddr2;
socklen_t cancelAddrLen;
#endif
_readStreams = [[OFMutableArray alloc] init];
_writeStreams = [[OFMutableArray alloc] init];
_queue = [[OFMutableArray alloc] init];
_queueInfo = [[OFDataArray alloc]
initWithItemSize: sizeof(int)];
_queueFDs = [[OFDataArray alloc] initWithItemSize: sizeof(int)];
#ifndef _WIN32
if (pipe(_cancelFD))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
#else
/* Make sure WSAStartup has been called */
[OFTCPSocket class];
_cancelFD[0] = socket(AF_INET, SOCK_DGRAM, 0);
_cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0);
if (_cancelFD[0] == INVALID_SOCKET ||
_cancelFD[1] == INVALID_SOCKET)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
_cancelAddr.sin_family = AF_INET;
_cancelAddr.sin_port = 0;
_cancelAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
cancelAddr2 = _cancelAddr;
if (bind(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
sizeof(_cancelAddr)) || bind(_cancelFD[1],
(struct sockaddr*)&cancelAddr2, sizeof(cancelAddr2)))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
cancelAddrLen = sizeof(_cancelAddr);
if (getsockname(_cancelFD[0], (struct sockaddr*)&_cancelAddr,
&cancelAddrLen))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
#endif
_maxFD = _cancelFD[0];
_FDToStream = [self allocMemoryWithSize: sizeof(OFStream*)
count: _maxFD + 1];
_FDToStream[_cancelFD[0]] = nil;
#ifdef OF_HAVE_THREADS
_mutex = [[OFMutex alloc] init];
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
close(_cancelFD[0]);
close(_cancelFD[1]);
[_readStreams release];
[_writeStreams release];
[_queue release];
[_queueInfo release];
[_queueFDs release];
#ifdef OF_HAVE_THREADS
[_mutex release];
#endif
[super dealloc];
}
- (id <OFStreamObserverDelegate>)delegate
{
return _delegate;
}
- (void)setDelegate: (id <OFStreamObserverDelegate>)delegate
{
_delegate = delegate;
}
- (void)addStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[_mutex lock];
#endif
@try {
int qi = QUEUE_ADD | QUEUE_READ;
int fd = [stream fileDescriptorForReading];
[_queue addObject: stream];
[_queueInfo addItem: &qi];
[_queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[_mutex unlock];
#endif
}
[self cancel];
}
- (void)addStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[_mutex lock];
#endif
@try {
int qi = QUEUE_ADD | QUEUE_WRITE;
int fd = [stream fileDescriptorForWriting];
[_queue addObject: stream];
[_queueInfo addItem: &qi];
[_queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[_mutex unlock];
#endif
}
[self cancel];
}
- (void)removeStreamForReading: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[_mutex lock];
#endif
@try {
int qi = QUEUE_REMOVE | QUEUE_READ;
int fd = [stream fileDescriptorForReading];
[_queue addObject: stream];
[_queueInfo addItem: &qi];
[_queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[_mutex unlock];
#endif
}
[self cancel];
}
- (void)removeStreamForWriting: (OFStream*)stream
{
#ifdef OF_HAVE_THREADS
[_mutex lock];
#endif
@try {
int qi = QUEUE_REMOVE | QUEUE_WRITE;
int fd = [stream fileDescriptorForWriting];
[_queue addObject: stream];
[_queueInfo addItem: &qi];
[_queueFDs addItem: &fd];
} @finally {
#ifdef OF_HAVE_THREADS
[_mutex unlock];
#endif
}
[self cancel];
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
|
︙ | | | ︙ | |
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
|
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)OF_processQueue
{
#ifdef OF_HAVE_THREADS
[mutex lock];
#endif
@try {
OFStream **queueObjects = [queue objects];
int *queueInfoItems = [queueInfo items];
int *queueFDsItems = [queueFDs items];
size_t i, count = [queue count];
for (i = 0; i < count; i++) {
OFStream *stream = queueObjects[i];
int action = queueInfoItems[i];
int fd = queueFDsItems[i];
if ((action & QUEUE_ACTION) == QUEUE_ADD) {
if (fd > maxFD) {
maxFD = fd;
FDToStream = [self
resizeMemory: FDToStream
size: sizeof(OFStream*)
count: maxFD + 1];
}
FDToStream[fd] = stream;
}
if ((action & QUEUE_ACTION) == QUEUE_REMOVE) {
/* FIXME: Maybe downsize? */
FDToStream[fd] = nil;
}
switch (action) {
case QUEUE_ADD | QUEUE_READ:
[readStreams addObject: stream];
[self OF_addFileDescriptorForReading: fd];
break;
case QUEUE_ADD | QUEUE_WRITE:
[writeStreams addObject: stream];
[self OF_addFileDescriptorForWriting: fd];
break;
case QUEUE_REMOVE | QUEUE_READ:
[readStreams removeObjectIdenticalTo: stream];
[self OF_removeFileDescriptorForReading: fd];
break;
case QUEUE_REMOVE | QUEUE_WRITE:
[writeStreams removeObjectIdenticalTo: stream];
[self OF_removeFileDescriptorForWriting: fd];
break;
default:
assert(0);
}
}
[queue removeAllObjects];
[queueInfo removeAllItems];
[queueFDs removeAllItems];
} @finally {
#ifdef OF_HAVE_THREADS
[mutex unlock];
#endif
}
}
- (void)observe
{
[self observeWithTimeout: -1];
}
- (BOOL)observeWithTimeout: (double)timeout
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)cancel
{
#ifndef _WIN32
OF_ENSURE(write(cancelFD[1], "", 1) > 0);
#else
OF_ENSURE(sendto(cancelFD[1], "", 1, 0, (struct sockaddr*)&cancelAddr,
sizeof(cancelAddr)) > 0);
#endif
}
- (BOOL)OF_processCache
{
OFStream **objects = [readStreams objects];
size_t i, count = [readStreams count];
BOOL foundInCache = NO;
for (i = 0; i < count; i++) {
if ([objects[i] pendingBytes] > 0 &&
![objects[i] OF_isWaitingForDelimiter]) {
void *pool = objc_autoreleasePoolPush();
if ([delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[delegate streamIsReadyForReading: objects[i]];
foundInCache = YES;
objc_autoreleasePoolPop(pool);
}
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
|
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)OF_processQueue
{
#ifdef OF_HAVE_THREADS
[_mutex lock];
#endif
@try {
OFStream **queueObjects = [_queue objects];
int *queueInfoItems = [_queueInfo items];
int *queueFDsItems = [_queueFDs items];
size_t i, count = [_queue count];
for (i = 0; i < count; i++) {
OFStream *stream = queueObjects[i];
int action = queueInfoItems[i];
int fd = queueFDsItems[i];
if ((action & QUEUE_ACTION) == QUEUE_ADD) {
if (fd > _maxFD) {
_maxFD = fd;
_FDToStream = [self
resizeMemory: _FDToStream
size: sizeof(OFStream*)
count: _maxFD + 1];
}
_FDToStream[fd] = stream;
}
if ((action & QUEUE_ACTION) == QUEUE_REMOVE) {
/* FIXME: Maybe downsize? */
_FDToStream[fd] = nil;
}
switch (action) {
case QUEUE_ADD | QUEUE_READ:
[_readStreams addObject: stream];
[self OF_addFileDescriptorForReading: fd];
break;
case QUEUE_ADD | QUEUE_WRITE:
[_writeStreams addObject: stream];
[self OF_addFileDescriptorForWriting: fd];
break;
case QUEUE_REMOVE | QUEUE_READ:
[_readStreams removeObjectIdenticalTo: stream];
[self OF_removeFileDescriptorForReading: fd];
break;
case QUEUE_REMOVE | QUEUE_WRITE:
[_writeStreams removeObjectIdenticalTo: stream];
[self OF_removeFileDescriptorForWriting: fd];
break;
default:
assert(0);
}
}
[_queue removeAllObjects];
[_queueInfo removeAllItems];
[_queueFDs removeAllItems];
} @finally {
#ifdef OF_HAVE_THREADS
[_mutex unlock];
#endif
}
}
- (void)observe
{
[self observeWithTimeout: -1];
}
- (BOOL)observeWithTimeout: (double)timeout
{
[self doesNotRecognizeSelector: _cmd];
abort();
}
- (void)cancel
{
#ifndef _WIN32
OF_ENSURE(write(_cancelFD[1], "", 1) > 0);
#else
OF_ENSURE(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr*)&_cancelAddr,
sizeof(_cancelAddr)) > 0);
#endif
}
- (BOOL)OF_processCache
{
OFStream **objects = [_readStreams objects];
size_t i, count = [_readStreams count];
BOOL foundInCache = NO;
for (i = 0; i < count; i++) {
if ([objects[i] pendingBytes] > 0 &&
![objects[i] OF_isWaitingForDelimiter]) {
void *pool = objc_autoreleasePoolPush();
if ([_delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[_delegate streamIsReadyForReading: objects[i]];
foundInCache = YES;
objc_autoreleasePoolPop(pool);
}
}
|
︙ | | | ︙ | |
Modified src/OFStreamObserver_kqueue.h
from [88b5dfe561]
to [5159b313b1].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFStreamObserver.h"
@class OFDataArray;
@interface OFStreamObserver_kqueue: OFStreamObserver
{
int kernelQueue;
OFDataArray *changeList;
}
@end
|
|
|
|
16
17
18
19
20
21
22
23
24
25
26
|
#import "OFStreamObserver.h"
@class OFDataArray;
@interface OFStreamObserver_kqueue: OFStreamObserver
{
int _kernelQueue;
OFDataArray *_changeList;
}
@end
|
Modified src/OFStreamObserver_kqueue.m
from [fe73536f5b]
to [fd7c063d3b].
︙ | | | ︙ | |
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
|
@implementation OFStreamObserver_kqueue
- init
{
self = [super init];
@try {
if ((kernelQueue = kqueue()) == -1)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
changeList = [[OFDataArray alloc] initWithItemSize:
sizeof(struct kevent)];
[self OF_addFileDescriptorForReading: cancelFD[0]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
close(kernelQueue);
[changeList release];
[super dealloc];
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
struct kevent event;
if ([changeList count] >= INT_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
[changeList addItem: &event];
}
- (void)OF_addFileDescriptorForWriting: (int)fd
{
struct kevent event;
if ([changeList count] >= INT_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
[changeList addItem: &event];
}
- (void)OF_removeFileDescriptorForReading: (int)fd
{
struct kevent event;
EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
[changeList addItem: &event];
}
- (void)OF_removeFileDescriptorForWriting: (int)fd
{
struct kevent event;
EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
[changeList addItem: &event];
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
struct timespec timespec;
struct kevent eventList[EVENTLIST_SIZE];
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
@implementation OFStreamObserver_kqueue
- init
{
self = [super init];
@try {
if ((_kernelQueue = kqueue()) == -1)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
_changeList = [[OFDataArray alloc] initWithItemSize:
sizeof(struct kevent)];
[self OF_addFileDescriptorForReading: _cancelFD[0]];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
close(_kernelQueue);
[_changeList release];
[super dealloc];
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
struct kevent event;
if ([_changeList count] >= INT_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
[_changeList addItem: &event];
}
- (void)OF_addFileDescriptorForWriting: (int)fd
{
struct kevent event;
if ([_changeList count] >= INT_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
[_changeList addItem: &event];
}
- (void)OF_removeFileDescriptorForReading: (int)fd
{
struct kevent event;
EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
[_changeList addItem: &event];
}
- (void)OF_removeFileDescriptorForWriting: (int)fd
{
struct kevent event;
EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
[_changeList addItem: &event];
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
struct timespec timespec;
struct kevent eventList[EVENTLIST_SIZE];
|
︙ | | | ︙ | |
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
events = kevent(kernelQueue, [changeList items],
(int)[changeList count], eventList, EVENTLIST_SIZE,
(timeout == -1 ? NULL : ×pec));
if (events < 0)
return NO;
[changeList removeAllItems];
if (events == 0)
return NO;
for (i = 0; i < events; i++) {
if (eventList[i].ident == cancelFD[0]) {
char buffer;
OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
continue;
}
realEvents++;
pool = objc_autoreleasePoolPush();
if (eventList[i].flags & EV_ERROR) {
if ([delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[delegate streamDidReceiveException:
FDToStream[eventList[i].ident]];
objc_autoreleasePoolPop(pool);
continue;
}
switch (eventList[i].filter) {
case EVFILT_READ:
if ([delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[delegate streamIsReadyForReading:
FDToStream[eventList[i].ident]];
break;
case EVFILT_WRITE:
if ([delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[delegate streamIsReadyForWriting:
FDToStream[eventList[i].ident]];
break;
default:
assert(0);
}
objc_autoreleasePoolPop(pool);
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
events = kevent(_kernelQueue, [_changeList items],
(int)[_changeList count], eventList, EVENTLIST_SIZE,
(timeout == -1 ? NULL : ×pec));
if (events < 0)
return NO;
[_changeList removeAllItems];
if (events == 0)
return NO;
for (i = 0; i < events; i++) {
if (eventList[i].ident == _cancelFD[0]) {
char buffer;
OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
continue;
}
realEvents++;
pool = objc_autoreleasePoolPush();
if (eventList[i].flags & EV_ERROR) {
if ([_delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[_delegate streamDidReceiveException:
_FDToStream[eventList[i].ident]];
objc_autoreleasePoolPop(pool);
continue;
}
switch (eventList[i].filter) {
case EVFILT_READ:
if ([_delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[_delegate streamIsReadyForReading:
_FDToStream[eventList[i].ident]];
break;
case EVFILT_WRITE:
if ([_delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[_delegate streamIsReadyForWriting:
_FDToStream[eventList[i].ident]];
break;
default:
assert(0);
}
objc_autoreleasePoolPop(pool);
}
|
︙ | | | ︙ | |
Modified src/OFStreamObserver_poll.h
from [d8c774bd02]
to [a9e9e56b91].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
|
#import "OFStreamObserver.h"
@class OFDataArray;
@interface OFStreamObserver_poll: OFStreamObserver
{
OFDataArray *FDs;
}
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
|
#import "OFStreamObserver.h"
@class OFDataArray;
@interface OFStreamObserver_poll: OFStreamObserver
{
OFDataArray *_FDs;
}
@end
|
Modified src/OFStreamObserver_poll.m
from [5c8293cbf9]
to [1648f30d0f].
︙ | | | ︙ | |
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
|
- init
{
self = [super init];
@try {
struct pollfd p = { 0, POLLIN, 0 };
FDs = [[OFDataArray alloc] initWithItemSize:
sizeof(struct pollfd)];
p.fd = cancelFD[0];
[FDs addItem: &p];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[FDs release];
[super dealloc];
}
- (void)OF_addFileDescriptor: (int)fd
withEvents: (short)events
{
struct pollfd *FDs_ = [FDs items];
size_t i, count = [FDs count];
BOOL found = NO;
for (i = 0; i < count; i++) {
if (FDs_[i].fd == fd) {
FDs_[i].events |= events;
found = YES;
break;
}
}
if (!found) {
struct pollfd p = { fd, events | POLLERR, 0 };
[FDs addItem: &p];
}
}
- (void)OF_removeFileDescriptor: (int)fd
withEvents: (short)events
{
struct pollfd *FDs_ = [FDs items];
size_t i, nFDs = [FDs count];
for (i = 0; i < nFDs; i++) {
if (FDs_[i].fd == fd) {
FDs_[i].events &= ~events;
if ((FDs_[i].events & ~POLLERR) == 0)
[FDs removeItemAtIndex: i];
break;
}
}
}
- (void)OF_addFileDescriptorForReading: (int)fd
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
- init
{
self = [super init];
@try {
struct pollfd p = { 0, POLLIN, 0 };
_FDs = [[OFDataArray alloc] initWithItemSize:
sizeof(struct pollfd)];
p.fd = _cancelFD[0];
[_FDs addItem: &p];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_FDs release];
[super dealloc];
}
- (void)OF_addFileDescriptor: (int)fd
withEvents: (short)events
{
struct pollfd *FDs = [_FDs items];
size_t i, count = [_FDs count];
BOOL found = NO;
for (i = 0; i < count; i++) {
if (FDs[i].fd == fd) {
FDs[i].events |= events;
found = YES;
break;
}
}
if (!found) {
struct pollfd p = { fd, events | POLLERR, 0 };
[_FDs addItem: &p];
}
}
- (void)OF_removeFileDescriptor: (int)fd
withEvents: (short)events
{
struct pollfd *FDs = [_FDs items];
size_t i, nFDs = [_FDs count];
for (i = 0; i < nFDs; i++) {
if (FDs[i].fd == fd) {
FDs[i].events &= ~events;
if ((FDs[i].events & ~POLLERR) == 0)
[_FDs removeItemAtIndex: i];
break;
}
}
}
- (void)OF_addFileDescriptorForReading: (int)fd
|
︙ | | | ︙ | |
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
[self OF_removeFileDescriptor: fd
withEvents: POLLOUT];
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
struct pollfd *FDs_;
size_t i, nFDs, realEvents = 0;
[self OF_processQueue];
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
FDs_ = [FDs items];
nFDs = [FDs count];
#ifdef OPEN_MAX
if (nFDs > OPEN_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif
if (poll(FDs_, (nfds_t)nFDs,
(int)(timeout != -1 ? timeout * 1000 : -1)) < 1)
return NO;
for (i = 0; i < nFDs; i++) {
pool = objc_autoreleasePoolPush();
if (FDs_[i].revents & POLLIN) {
if (FDs_[i].fd == cancelFD[0]) {
char buffer;
OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
FDs_[i].revents = 0;
objc_autoreleasePoolPop(pool);
continue;
}
if ([delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[delegate streamIsReadyForReading:
FDToStream[FDs_[i].fd]];
realEvents++;
}
if (FDs_[i].revents & POLLOUT) {
if ([delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[delegate streamIsReadyForWriting:
FDToStream[FDs_[i].fd]];
realEvents++;
}
if (FDs_[i].revents & POLLERR) {
if ([delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[delegate streamDidReceiveException:
FDToStream[FDs_[i].fd]];
realEvents++;
}
FDs_[i].revents = 0;
objc_autoreleasePoolPop(pool);
}
if (realEvents == 0)
return NO;
return YES;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
|
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
[self OF_removeFileDescriptor: fd
withEvents: POLLOUT];
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
struct pollfd *FDs;
size_t i, nFDs, realEvents = 0;
[self OF_processQueue];
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
FDs = [_FDs items];
nFDs = [_FDs count];
#ifdef OPEN_MAX
if (nFDs > OPEN_MAX)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
#endif
if (poll(FDs, (nfds_t)nFDs,
(int)(timeout != -1 ? timeout * 1000 : -1)) < 1)
return NO;
for (i = 0; i < nFDs; i++) {
pool = objc_autoreleasePoolPush();
if (FDs[i].revents & POLLIN) {
if (FDs[i].fd == _cancelFD[0]) {
char buffer;
OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
FDs[i].revents = 0;
objc_autoreleasePoolPop(pool);
continue;
}
if ([_delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[_delegate streamIsReadyForReading:
_FDToStream[FDs[i].fd]];
realEvents++;
}
if (FDs[i].revents & POLLOUT) {
if ([_delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[_delegate streamIsReadyForWriting:
_FDToStream[FDs[i].fd]];
realEvents++;
}
if (FDs[i].revents & POLLERR) {
if ([_delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[_delegate streamDidReceiveException:
_FDToStream[FDs[i].fd]];
realEvents++;
}
FDs[i].revents = 0;
objc_autoreleasePoolPop(pool);
}
if (realEvents == 0)
return NO;
return YES;
}
@end
|
Modified src/OFStreamObserver_select.h
from [ef59e082ab]
to [bbd983d332].
︙ | | | ︙ | |
25
26
27
28
29
30
31
32
33
34
35
36
|
# include <sys/select.h>
#endif
#import "OFStreamObserver.h"
@interface OFStreamObserver_select: OFStreamObserver
{
fd_set readFDs;
fd_set writeFDs;
fd_set exceptFDs;
}
@end
|
<
<
|
|
25
26
27
28
29
30
31
32
33
34
|
# include <sys/select.h>
#endif
#import "OFStreamObserver.h"
@interface OFStreamObserver_select: OFStreamObserver
{
fd_set _readFDs, _writeFDs, _exceptFDs;
}
@end
|
Modified src/OFStreamObserver_select.m
from [ea4f833523]
to [f904878755].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
#import "macros.h"
@implementation OFStreamObserver_select
- init
{
self = [super init];
FD_ZERO(&readFDs);
FD_ZERO(&writeFDs);
FD_SET(cancelFD[0], &readFDs);
return self;
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
FD_SET(fd, &readFDs);
FD_SET(fd, &exceptFDs);
}
- (void)OF_addFileDescriptorForWriting: (int)fd
{
FD_SET(fd, &writeFDs);
FD_SET(fd, &exceptFDs);
}
- (void)OF_removeFileDescriptorForReading: (int)fd
{
FD_CLR(fd, &readFDs);
if (!FD_ISSET(fd, &writeFDs))
FD_CLR(fd, &exceptFDs);
}
- (void)OF_removeFileDescriptorForWriting: (int)fd
{
FD_CLR(fd, &writeFDs);
if (!FD_ISSET(fd, &readFDs))
FD_CLR(fd, &exceptFDs);
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
OFStream **objects;
fd_set readFDs_;
fd_set writeFDs_;
fd_set exceptFDs_;
struct timeval time;
size_t i, count, realEvents = 0;
[self OF_processQueue];
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
#ifdef FD_COPY
FD_COPY(&readFDs, &readFDs_);
FD_COPY(&writeFDs, &writeFDs_);
FD_COPY(&exceptFDs, &exceptFDs_);
#else
readFDs_ = readFDs;
writeFDs_ = writeFDs;
exceptFDs_ = exceptFDs;
#endif
/*
* We cast to int before assigning to tv_usec in order to avoid a
* warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
* however, this is not available on Win32. As an int should always
* satisfy the required range, we just cast to int.
*/
time.tv_sec = (time_t)timeout;
time.tv_usec = (int)((timeout - time.tv_sec) * 1000);
if (select((int)maxFD + 1, &readFDs_, &writeFDs_, &exceptFDs_,
(timeout != -1 ? &time : NULL)) < 1)
return NO;
if (FD_ISSET(cancelFD[0], &readFDs_)) {
char buffer;
#ifndef _WIN32
OF_ENSURE(read(cancelFD[0], &buffer, 1) > 0);
#else
OF_ENSURE(recvfrom(cancelFD[0], &buffer, 1, 0, NULL, NULL) > 0);
#endif
}
objects = [readStreams objects];
count = [readStreams count];
for (i = 0; i < count; i++) {
int fd = [objects[i] fileDescriptorForReading];
pool = objc_autoreleasePoolPush();
if (FD_ISSET(fd, &readFDs_)) {
if ([delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[delegate streamIsReadyForReading: objects[i]];
realEvents++;
}
if (FD_ISSET(fd, &exceptFDs_)) {
if ([delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[delegate streamDidReceiveException:
objects[i]];
/*
* Prevent calling it twice in case the FD is in both
* sets.
*/
FD_CLR(fd, &exceptFDs_);
realEvents++;
}
objc_autoreleasePoolPop(pool);
}
objects = [writeStreams objects];
count = [writeStreams count];
for (i = 0; i < count; i++) {
int fd = [objects[i] fileDescriptorForWriting];
pool = objc_autoreleasePoolPush();
if (FD_ISSET(fd, &writeFDs_)) {
if ([delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[delegate streamIsReadyForWriting: objects[i]];
realEvents++;
}
if (FD_ISSET(fd, &exceptFDs_)) {
if ([delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[delegate streamDidReceiveException:
objects[i]];
realEvents++;
}
objc_autoreleasePoolPop(pool);
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
#import "macros.h"
@implementation OFStreamObserver_select
- init
{
self = [super init];
FD_ZERO(&_readFDs);
FD_ZERO(&_writeFDs);
FD_SET(_cancelFD[0], &_readFDs);
return self;
}
- (void)OF_addFileDescriptorForReading: (int)fd
{
FD_SET(fd, &_readFDs);
FD_SET(fd, &_exceptFDs);
}
- (void)OF_addFileDescriptorForWriting: (int)fd
{
FD_SET(fd, &_writeFDs);
FD_SET(fd, &_exceptFDs);
}
- (void)OF_removeFileDescriptorForReading: (int)fd
{
FD_CLR(fd, &_readFDs);
if (!FD_ISSET(fd, &_writeFDs))
FD_CLR(fd, &_exceptFDs);
}
- (void)OF_removeFileDescriptorForWriting: (int)fd
{
FD_CLR(fd, &_writeFDs);
if (!FD_ISSET(fd, &_readFDs))
FD_CLR(fd, &_exceptFDs);
}
- (BOOL)observeWithTimeout: (double)timeout
{
void *pool = objc_autoreleasePoolPush();
OFStream **objects;
fd_set readFDs;
fd_set writeFDs;
fd_set exceptFDs;
struct timeval time;
size_t i, count, realEvents = 0;
[self OF_processQueue];
if ([self OF_processCache]) {
objc_autoreleasePoolPop(pool);
return YES;
}
objc_autoreleasePoolPop(pool);
#ifdef FD_COPY
FD_COPY(&_readFDs, &readFDs);
FD_COPY(&_writeFDs, &writeFDs);
FD_COPY(&_exceptFDs, &exceptFDs);
#else
readFDs = _readFDs;
writeFDs = _writeFDs;
exceptFDs = _exceptFDs;
#endif
/*
* We cast to int before assigning to tv_usec in order to avoid a
* warning with Apple GCC on PPC. POSIX defines this as suseconds_t,
* however, this is not available on Win32. As an int should always
* satisfy the required range, we just cast to int.
*/
time.tv_sec = (time_t)timeout;
time.tv_usec = (int)((timeout - time.tv_sec) * 1000);
if (select((int)_maxFD + 1, &readFDs, &writeFDs, &exceptFDs,
(timeout != -1 ? &time : NULL)) < 1)
return NO;
if (FD_ISSET(_cancelFD[0], &readFDs)) {
char buffer;
#ifndef _WIN32
OF_ENSURE(read(_cancelFD[0], &buffer, 1) > 0);
#else
OF_ENSURE(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL,
NULL) > 0);
#endif
}
objects = [_readStreams objects];
count = [_readStreams count];
for (i = 0; i < count; i++) {
int fd = [objects[i] fileDescriptorForReading];
pool = objc_autoreleasePoolPush();
if (FD_ISSET(fd, &readFDs)) {
if ([_delegate respondsToSelector:
@selector(streamIsReadyForReading:)])
[_delegate streamIsReadyForReading: objects[i]];
realEvents++;
}
if (FD_ISSET(fd, &exceptFDs)) {
if ([_delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[_delegate streamDidReceiveException:
objects[i]];
/*
* Prevent calling it twice in case the FD is in both
* sets.
*/
FD_CLR(fd, &exceptFDs);
realEvents++;
}
objc_autoreleasePoolPop(pool);
}
objects = [_writeStreams objects];
count = [_writeStreams count];
for (i = 0; i < count; i++) {
int fd = [objects[i] fileDescriptorForWriting];
pool = objc_autoreleasePoolPush();
if (FD_ISSET(fd, &writeFDs)) {
if ([_delegate respondsToSelector:
@selector(streamIsReadyForWriting:)])
[_delegate streamIsReadyForWriting: objects[i]];
realEvents++;
}
if (FD_ISSET(fd, &exceptFDs)) {
if ([_delegate respondsToSelector:
@selector(streamDidReceiveException:)])
[_delegate streamDidReceiveException:
objects[i]];
realEvents++;
}
objc_autoreleasePoolPop(pool);
}
|
︙ | | | ︙ | |
Modified src/OFStreamSocket.h
from [54613b8cfd]
to [f3d324a9cc].
︙ | | | ︙ | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#endif
/*!
* @brief A class which provides functions to create and use stream sockets.
*/
@interface OFStreamSocket: OFStream
{
int sock;
BOOL atEndOfStream;
}
/*!
* @brief Returns a new, autoreleased OFTCPSocket.
*
* @return A new, autoreleased OFTCPSocket
*/
+ (instancetype)socket;
@end
|
|
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#endif
/*!
* @brief A class which provides functions to create and use stream sockets.
*/
@interface OFStreamSocket: OFStream
{
int _socket;
BOOL _atEndOfStream;
}
/*!
* @brief Returns a new, autoreleased OFTCPSocket.
*
* @return A new, autoreleased OFTCPSocket
*/
+ (instancetype)socket;
@end
|
Modified src/OFStreamSocket.m
from [902270c256]
to [a7e950a736].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
+ (instancetype)socket
{
return [[[self alloc] init] autorelease];
}
- (BOOL)lowlevelIsAtEndOfStream
{
return atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
ssize_t ret;
if (sock == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (atEndOfStream) {
OFReadFailedException *e;
e = [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
#ifndef _WIN32
e->errNo = ENOTCONN;
#else
e->errNo = WSAENOTCONN;
#endif
@throw e;
}
if ((ret = recv(sock, buffer, length, 0)) < 0)
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
if (ret == 0)
atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
if (sock == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (atEndOfStream) {
OFWriteFailedException *e;
e = [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
#ifndef _WIN32
e->errNo = ENOTCONN;
#else
e->errNo = WSAENOTCONN;
#endif
@throw e;
}
if (send(sock, buffer, length, 0) < length)
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
#ifdef _WIN32
- (void)setBlocking: (BOOL)enable
{
u_long v = enable;
blocking = enable;
if (ioctlsocket(sock, FIONBIO, &v) == SOCKET_ERROR)
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
}
#endif
- (int)fileDescriptorForReading
{
return sock;
}
- (int)fileDescriptorForWriting
{
return sock;
}
- (void)close
{
if (sock == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
close(sock);
sock = INVALID_SOCKET;
atEndOfStream = NO;
}
- (void)dealloc
{
if (sock != INVALID_SOCKET)
[self close];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
<
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
+ (instancetype)socket
{
return [[[self alloc] init] autorelease];
}
- (BOOL)lowlevelIsAtEndOfStream
{
return _atEndOfStream;
}
- (size_t)lowlevelReadIntoBuffer: (void*)buffer
length: (size_t)length
{
ssize_t ret;
if (_socket == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (_atEndOfStream) {
OFReadFailedException *e;
e = [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
#ifndef _WIN32
e->_errNo = ENOTCONN;
#else
e->_errNo = WSAENOTCONN;
#endif
@throw e;
}
if ((ret = recv(_socket, buffer, length, 0)) < 0)
@throw [OFReadFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
if (ret == 0)
_atEndOfStream = YES;
return ret;
}
- (void)lowlevelWriteBuffer: (const void*)buffer
length: (size_t)length
{
if (_socket == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (_atEndOfStream) {
OFWriteFailedException *e;
e = [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
#ifndef _WIN32
e->_errNo = ENOTCONN;
#else
e->_errNo = WSAENOTCONN;
#endif
@throw e;
}
if (send(_socket, buffer, length, 0) < length)
@throw [OFWriteFailedException exceptionWithClass: [self class]
stream: self
requestedLength: length];
}
#ifdef _WIN32
- (void)setBlocking: (BOOL)enable
{
u_long v = enable;
_blocking = enable;
if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR)
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
}
#endif
- (int)fileDescriptorForReading
{
return _socket;
}
- (int)fileDescriptorForWriting
{
return _socket;
}
- (void)close
{
if (_socket == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
close(_socket);
_socket = INVALID_SOCKET;
_atEndOfStream = NO;
}
- (void)dealloc
{
if (_socket != INVALID_SOCKET)
[self close];
[super dealloc];
}
@end
|
Modified src/OFString_UTF8.h
from [9d742edbb7]
to [f4f94da890].
︙ | | | ︙ | |
18
19
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
|
@interface OFString_UTF8: OFString
{
@public
/*
* A pointer to the actual data.
*
* Since constant strings don't have s_store, they have to malloc it on
* the first access. Strings created at runtime just set the pointer to
* &s_store.
*/
struct of_string_utf8_ivars {
char *cString;
size_t cStringLength;
BOOL isUTF8;
size_t length;
BOOL hashed;
uint32_t hash;
char *freeWhenDone;
} *restrict s;
struct of_string_utf8_ivars s_store;
}
- OF_initWithUTF8String: (const char*)UTF8String
length: (size_t)UTF8StringLength
storage: (char*)storage;
@end
|
|
|
|
|
|
|
18
19
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
|
@interface OFString_UTF8: OFString
{
@public
/*
* A pointer to the actual data.
*
* Since constant strings don't have _storage, they have to malloc it
* on the first access. Strings created at runtime just set the pointer
* to &_storage.
*/
struct of_string_utf8_ivars {
char *cString;
size_t cStringLength;
BOOL isUTF8;
size_t length;
BOOL hashed;
uint32_t hash;
char *freeWhenDone;
} *restrict _s;
struct of_string_utf8_ivars _storage;
}
- OF_initWithUTF8String: (const char*)UTF8String
length: (size_t)UTF8StringLength
storage: (char*)storage;
@end
|
︙ | | | ︙ | |
Modified src/OFString_UTF8.m
from [0615761918]
to [503640087e].
︙ | | | ︙ | |
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
@implementation OFString_UTF8
- init
{
self = [super init];
@try {
s = &s_store;
s->cString = [self allocMemoryWithSize: 1];
s->cString[0] = '\0';
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
@implementation OFString_UTF8
- init
{
self = [super init];
@try {
_s = &_storage;
_s->cString = [self allocMemoryWithSize: 1];
_s->cString[0] = '\0';
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
@try {
if (UTF8StringLength >= 3 &&
!memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
s = &s_store;
s->cString = storage;
s->cStringLength = UTF8StringLength;
switch (of_string_utf8_check(UTF8String, UTF8StringLength,
&s->length)) {
case 1:
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
memcpy(s->cString, UTF8String, UTF8StringLength);
s->cString[UTF8StringLength] = 0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
|
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
@try {
if (UTF8StringLength >= 3 &&
!memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
_s = &_storage;
_s->cString = storage;
_s->cStringLength = UTF8StringLength;
switch (of_string_utf8_check(UTF8String, UTF8StringLength,
&_s->length)) {
case 1:
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
memcpy(_s->cString, UTF8String, UTF8StringLength);
_s->cString[UTF8StringLength] = 0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
if (encoding == OF_STRING_ENCODING_UTF_8 &&
cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) {
cString += 3;
cStringLength -= 3;
}
s = &s_store;
s->cString = [self allocMemoryWithSize: cStringLength + 1];
s->cStringLength = cStringLength;
if (encoding == OF_STRING_ENCODING_UTF_8 ||
encoding == OF_STRING_ENCODING_ASCII) {
switch (of_string_utf8_check(cString, cStringLength,
&s->length)) {
case 1:
if (encoding == OF_STRING_ENCODING_ASCII)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
memcpy(s->cString, cString, cStringLength);
s->cString[cStringLength] = 0;
return self;
}
/* All other encodings we support are single byte encodings */
s->length = cStringLength;
if (encoding == OF_STRING_ENCODING_ISO_8859_1) {
for (i = j = 0; i < cStringLength; i++) {
char buffer[4];
size_t bytes;
if (!(cString[i] & 0x80)) {
s->cString[j++] = cString[i];
continue;
}
s->isUTF8 = YES;
bytes = of_string_utf8_encode(
(uint8_t)cString[i], buffer);
if (bytes == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
s->cStringLength += bytes - 1;
s->cString = [self
resizeMemory: s->cString
size: s->cStringLength + 1];
memcpy(s->cString + j, buffer, bytes);
j += bytes;
}
s->cString[s->cStringLength] = 0;
return self;
}
switch (encoding) {
case OF_STRING_ENCODING_ISO_8859_15:
table = of_iso_8859_15;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
if (encoding == OF_STRING_ENCODING_UTF_8 &&
cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) {
cString += 3;
cStringLength -= 3;
}
_s = &_storage;
_s->cString = [self allocMemoryWithSize: cStringLength + 1];
_s->cStringLength = cStringLength;
if (encoding == OF_STRING_ENCODING_UTF_8 ||
encoding == OF_STRING_ENCODING_ASCII) {
switch (of_string_utf8_check(cString, cStringLength,
&_s->length)) {
case 1:
if (encoding == OF_STRING_ENCODING_ASCII)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
memcpy(_s->cString, cString, cStringLength);
_s->cString[cStringLength] = 0;
return self;
}
/* All other encodings we support are single byte encodings */
_s->length = cStringLength;
if (encoding == OF_STRING_ENCODING_ISO_8859_1) {
for (i = j = 0; i < cStringLength; i++) {
char buffer[4];
size_t bytes;
if (!(cString[i] & 0x80)) {
_s->cString[j++] = cString[i];
continue;
}
_s->isUTF8 = YES;
bytes = of_string_utf8_encode(
(uint8_t)cString[i], buffer);
if (bytes == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
_s->cStringLength += bytes - 1;
_s->cString = [self
resizeMemory: _s->cString
size: _s->cStringLength + 1];
memcpy(_s->cString + j, buffer, bytes);
j += bytes;
}
_s->cString[_s->cStringLength] = 0;
return self;
}
switch (encoding) {
case OF_STRING_ENCODING_ISO_8859_15:
table = of_iso_8859_15;
|
︙ | | | ︙ | |
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
|
for (i = j = 0; i < cStringLength; i++) {
char buffer[4];
of_unichar_t character;
size_t characterBytes;
if (!(cString[i] & 0x80)) {
s->cString[j++] = cString[i];
continue;
}
character = table[(uint8_t)cString[i]];
if (character == 0xFFFD)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
s->isUTF8 = YES;
characterBytes = of_string_utf8_encode(character,
buffer);
if (characterBytes == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
s->cStringLength += characterBytes - 1;
s->cString = [self resizeMemory: s->cString
size: s->cStringLength + 1];
memcpy(s->cString + j, buffer, characterBytes);
j += characterBytes;
}
s->cString[s->cStringLength] = 0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
>
|
|
|
|
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
for (i = j = 0; i < cStringLength; i++) {
char buffer[4];
of_unichar_t character;
size_t characterBytes;
if (!(cString[i] & 0x80)) {
_s->cString[j++] = cString[i];
continue;
}
character = table[(uint8_t)cString[i]];
if (character == 0xFFFD)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
_s->isUTF8 = YES;
characterBytes = of_string_utf8_encode(character,
buffer);
if (characterBytes == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
_s->cStringLength += characterBytes - 1;
_s->cString = [self
resizeMemory: _s->cString
size: _s->cStringLength + 1];
memcpy(_s->cString + j, buffer, characterBytes);
j += characterBytes;
}
_s->cString[_s->cStringLength] = 0;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
|
if (UTF8StringLength >= 3 &&
!memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
s = &s_store;
s->cString = (char*)UTF8String;
s->cStringLength = UTF8StringLength;
if (freeWhenDone)
s->freeWhenDone = UTF8String;
switch (of_string_utf8_check(UTF8String, UTF8StringLength,
&s->length)) {
case 1:
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
s = &s_store;
s->cStringLength = [string UTF8StringLength];
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]])
s->isUTF8 = ((OFString_UTF8*)string)->s->isUTF8;
else
s->isUTF8 = YES;
s->length = [string length];
s->cString = [self allocMemoryWithSize: s->cStringLength + 1];
memcpy(s->cString, [string UTF8String], s->cStringLength + 1);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithCharacters: (const of_unichar_t*)characters
length: (size_t)length
{
self = [super init];
@try {
size_t i, j = 0;
s = &s_store;
s->cString = [self allocMemoryWithSize: (length * 4) + 1];
s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
size_t len = of_string_utf8_encode(characters[i],
buffer);
switch (len) {
case 1:
s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
s->isUTF8 = YES;
memcpy(s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
s->cString[j] = '\0';
s->cStringLength = j;
@try {
s->cString = [self resizeMemory: s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
if (UTF8StringLength >= 3 &&
!memcmp(UTF8String, "\xEF\xBB\xBF", 3)) {
UTF8String += 3;
UTF8StringLength -= 3;
}
_s = &_storage;
_s->cString = (char*)UTF8String;
_s->cStringLength = UTF8StringLength;
if (freeWhenDone)
_s->freeWhenDone = UTF8String;
switch (of_string_utf8_check(UTF8String, UTF8StringLength,
&_s->length)) {
case 1:
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
_s = &_storage;
_s->cStringLength = [string UTF8StringLength];
if ([string isKindOfClass: [OFString_UTF8 class]] ||
[string isKindOfClass: [OFMutableString_UTF8 class]])
_s->isUTF8 = ((OFString_UTF8*)string)->_s->isUTF8;
else
_s->isUTF8 = YES;
_s->length = [string length];
_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
memcpy(_s->cString, [string UTF8String], _s->cStringLength + 1);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithCharacters: (const of_unichar_t*)characters
length: (size_t)length
{
self = [super init];
@try {
size_t i, j = 0;
_s = &_storage;
_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
_s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
size_t len = of_string_utf8_encode(characters[i],
buffer);
switch (len) {
case 1:
_s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
_s->isUTF8 = YES;
memcpy(_s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
_s->cString[j] = '\0';
_s->cStringLength = j;
@try {
_s->cString = [self resizeMemory: _s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
|
} else if (length > 0 && *string == 0xFFFE) {
swap = YES;
string++;
length--;
} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
swap = YES;
s = &s_store;
s->cString = [self allocMemoryWithSize: (length * 4) + 1];
s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
of_unichar_t character =
(swap ? OF_BSWAP16(string[i]) : string[i]);
size_t len;
|
|
|
|
|
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
|
} else if (length > 0 && *string == 0xFFFE) {
swap = YES;
string++;
length--;
} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
swap = YES;
_s = &_storage;
_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
_s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
of_unichar_t character =
(swap ? OF_BSWAP16(string[i]) : string[i]);
size_t len;
|
︙ | | | ︙ | |
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
|
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
character = (((character & 0x3FF) << 10) |
(nextCharacter & 0x3FF)) + 0x10000;
i++;
s->length--;
}
len = of_string_utf8_encode(character, buffer);
switch (len) {
case 1:
s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
s->isUTF8 = YES;
memcpy(s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
s->cString[j] = '\0';
s->cStringLength = j;
@try {
s->cString = [self resizeMemory: s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
|
|
|
|
|
|
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
|
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
character = (((character & 0x3FF) << 10) |
(nextCharacter & 0x3FF)) + 0x10000;
i++;
_s->length--;
}
len = of_string_utf8_encode(character, buffer);
switch (len) {
case 1:
_s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
_s->isUTF8 = YES;
memcpy(_s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
_s->cString[j] = '\0';
_s->cStringLength = j;
@try {
_s->cString = [self resizeMemory: _s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
|
} else if (length > 0 && *characters == 0xFFFE0000) {
swap = YES;
characters++;
length--;
} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
swap = YES;
s = &s_store;
s->cString = [self allocMemoryWithSize: (length * 4) + 1];
s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
size_t len = of_string_utf8_encode(
(swap ? OF_BSWAP32(characters[i]) : characters[i]),
buffer);
switch (len) {
case 1:
s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
s->isUTF8 = YES;
memcpy(s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
s->cString[j] = '\0';
s->cStringLength = j;
@try {
s->cString = [self resizeMemory: s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
|
|
|
|
|
|
|
|
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
|
} else if (length > 0 && *characters == 0xFFFE0000) {
swap = YES;
characters++;
length--;
} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
swap = YES;
_s = &_storage;
_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
_s->length = length;
for (i = 0; i < length; i++) {
char buffer[4];
size_t len = of_string_utf8_encode(
(swap ? OF_BSWAP32(characters[i]) : characters[i]),
buffer);
switch (len) {
case 1:
_s->cString[j++] = buffer[0];
break;
case 2:
case 3:
case 4:
_s->isUTF8 = YES;
memcpy(_s->cString + j, buffer, len);
j += len;
break;
default:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
}
_s->cString[j] = '\0';
_s->cStringLength = j;
@try {
_s->cString = [self resizeMemory: _s->cString
size: j + 1];
} @catch (OFOutOfMemoryException *e) {
/* We don't care, as we only tried to make it smaller */
}
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
|
int cStringLength;
if (format == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
s = &s_store;
if ((cStringLength = of_vasprintf(&tmp, [format UTF8String],
arguments)) == -1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
s->cStringLength = cStringLength;
@try {
switch (of_string_utf8_check(tmp, cStringLength,
&s->length)) {
case 1:
s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
s->cString = [self
allocMemoryWithSize: cStringLength + 1];
memcpy(s->cString, tmp, cStringLength + 1);
} @finally {
free(tmp);
}
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
|
|
|
|
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
|
int cStringLength;
if (format == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_s = &_storage;
if ((cStringLength = of_vasprintf(&tmp, [format UTF8String],
arguments)) == -1)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_s->cStringLength = cStringLength;
@try {
switch (of_string_utf8_check(tmp, cStringLength,
&_s->length)) {
case 1:
_s->isUTF8 = YES;
break;
case -1:
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
}
_s->cString = [self
allocMemoryWithSize: cStringLength + 1];
memcpy(_s->cString, tmp, cStringLength + 1);
} @finally {
free(tmp);
}
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | | ︙ | |
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
|
self = [super init];
@try {
OFString *component;
size_t i, cStringLength;
va_list argumentsCopy;
s = &s_store;
s->cStringLength = [firstComponent UTF8StringLength];
if ([firstComponent isKindOfClass: [OFString_UTF8 class]] ||
[firstComponent isKindOfClass:
[OFMutableString_UTF8 class]])
s->isUTF8 = ((OFString_UTF8*)firstComponent)->s->isUTF8;
else
s->isUTF8 = YES;
s->length = [firstComponent length];
/* Calculate length and see if we need UTF-8 */
va_copy(argumentsCopy, arguments);
while ((component = va_arg(argumentsCopy, OFString*)) != nil) {
s->cStringLength += 1 + [component UTF8StringLength];
s->length += 1 + [component length];
if ([component isKindOfClass: [OFString_UTF8 class]] ||
[component isKindOfClass:
[OFMutableString_UTF8 class]])
s->isUTF8 =
((OFString_UTF8*)component)->s->isUTF8;
else
s->isUTF8 = YES;
}
s->cString = [self allocMemoryWithSize: s->cStringLength + 1];
cStringLength = [firstComponent UTF8StringLength];
memcpy(s->cString, [firstComponent UTF8String], cStringLength);
i = cStringLength;
while ((component = va_arg(arguments, OFString*)) != nil) {
cStringLength = [component UTF8StringLength];
s->cString[i] = OF_PATH_DELIMITER;
memcpy(s->cString + i + 1, [component UTF8String],
cStringLength);
i += 1 + cStringLength;
}
s->cString[i] = '\0';
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
if (s != NULL && s->freeWhenDone != NULL)
free(s->freeWhenDone);
[super dealloc];
}
- (size_t)getCString: (char*)cString
maxLength: (size_t)maxLength
encoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_ASCII:
if (s->isUTF8)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* intentional fall-through */
case OF_STRING_ENCODING_UTF_8:
if (s->cStringLength + 1 > maxLength)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
memcpy(cString, s->cString, s->cStringLength + 1);
return s->cStringLength;
default:
return [super getCString: cString
maxLength: maxLength
encoding: encoding];
}
}
- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_ASCII:
if (s->isUTF8)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* intentional fall-through */
case OF_STRING_ENCODING_UTF_8:
return s->cString;
default:
return [super cStringWithEncoding: encoding];
}
}
- (const char*)UTF8String
{
return s->cString;
}
- (size_t)length
{
return s->length;
}
- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_UTF_8:
case OF_STRING_ENCODING_ASCII:
return s->cStringLength;
default:
return [super cStringLengthWithEncoding: encoding];
}
}
- (size_t)UTF8StringLength
{
return s->cStringLength;
}
- (BOOL)isEqual: (id)object
{
OFString_UTF8 *otherString;
if (object == self)
return YES;
if (![object isKindOfClass: [OFString class]])
return NO;
otherString = object;
if ([otherString UTF8StringLength] != s->cStringLength ||
[otherString length] != s->length)
return NO;
if (([otherString isKindOfClass: [OFString_UTF8 class]] ||
[otherString isKindOfClass: [OFMutableString_UTF8 class]]) &&
s->hashed && otherString->s->hashed &&
s->hash != otherString->s->hash)
return NO;
if (strcmp(s->cString, [otherString UTF8String]))
return NO;
return YES;
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
|
self = [super init];
@try {
OFString *component;
size_t i, cStringLength;
va_list argumentsCopy;
_s = &_storage;
_s->cStringLength = [firstComponent UTF8StringLength];
if ([firstComponent isKindOfClass: [OFString_UTF8 class]] ||
[firstComponent isKindOfClass:
[OFMutableString_UTF8 class]])
_s->isUTF8 =
((OFString_UTF8*)firstComponent)->_s->isUTF8;
else
_s->isUTF8 = YES;
_s->length = [firstComponent length];
/* Calculate length and see if we need UTF-8 */
va_copy(argumentsCopy, arguments);
while ((component = va_arg(argumentsCopy, OFString*)) != nil) {
_s->cStringLength += 1 + [component UTF8StringLength];
_s->length += 1 + [component length];
if ([component isKindOfClass: [OFString_UTF8 class]] ||
[component isKindOfClass:
[OFMutableString_UTF8 class]])
_s->isUTF8 =
((OFString_UTF8*)component)->_s->isUTF8;
else
_s->isUTF8 = YES;
}
_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
cStringLength = [firstComponent UTF8StringLength];
memcpy(_s->cString, [firstComponent UTF8String], cStringLength);
i = cStringLength;
while ((component = va_arg(arguments, OFString*)) != nil) {
cStringLength = [component UTF8StringLength];
_s->cString[i] = OF_PATH_DELIMITER;
memcpy(_s->cString + i + 1, [component UTF8String],
cStringLength);
i += 1 + cStringLength;
}
_s->cString[i] = '\0';
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
if (_s != NULL && _s->freeWhenDone != NULL)
free(_s->freeWhenDone);
[super dealloc];
}
- (size_t)getCString: (char*)cString
maxLength: (size_t)maxLength
encoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_ASCII:
if (_s->isUTF8)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* intentional fall-through */
case OF_STRING_ENCODING_UTF_8:
if (_s->cStringLength + 1 > maxLength)
@throw [OFOutOfRangeException
exceptionWithClass: [self class]];
memcpy(cString, _s->cString, _s->cStringLength + 1);
return _s->cStringLength;
default:
return [super getCString: cString
maxLength: maxLength
encoding: encoding];
}
}
- (const char*)cStringWithEncoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_ASCII:
if (_s->isUTF8)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
/* intentional fall-through */
case OF_STRING_ENCODING_UTF_8:
return _s->cString;
default:
return [super cStringWithEncoding: encoding];
}
}
- (const char*)UTF8String
{
return _s->cString;
}
- (size_t)length
{
return _s->length;
}
- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding
{
switch (encoding) {
case OF_STRING_ENCODING_UTF_8:
case OF_STRING_ENCODING_ASCII:
return _s->cStringLength;
default:
return [super cStringLengthWithEncoding: encoding];
}
}
- (size_t)UTF8StringLength
{
return _s->cStringLength;
}
- (BOOL)isEqual: (id)object
{
OFString_UTF8 *otherString;
if (object == self)
return YES;
if (![object isKindOfClass: [OFString class]])
return NO;
otherString = object;
if ([otherString UTF8StringLength] != _s->cStringLength ||
[otherString length] != _s->length)
return NO;
if (([otherString isKindOfClass: [OFString_UTF8 class]] ||
[otherString isKindOfClass: [OFMutableString_UTF8 class]]) &&
_s->hashed && otherString->_s->hashed &&
_s->hash != otherString->_s->hash)
return NO;
if (strcmp(_s->cString, [otherString UTF8String]))
return NO;
return YES;
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
|
︙ | | | ︙ | |
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
|
if (![object isKindOfClass: [OFString class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherString = (OFString*)object;
otherCStringLength = [otherString UTF8StringLength];
minimumCStringLength = (s->cStringLength > otherCStringLength
? otherCStringLength : s->cStringLength);
if ((compare = memcmp(s->cString, [otherString UTF8String],
minimumCStringLength)) == 0) {
if (s->cStringLength > otherCStringLength)
return OF_ORDERED_DESCENDING;
if (s->cStringLength < otherCStringLength)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (compare > 0)
return OF_ORDERED_DESCENDING;
else
|
|
|
|
|
|
|
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
|
if (![object isKindOfClass: [OFString class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherString = (OFString*)object;
otherCStringLength = [otherString UTF8StringLength];
minimumCStringLength = (_s->cStringLength > otherCStringLength
? otherCStringLength : _s->cStringLength);
if ((compare = memcmp(_s->cString, [otherString UTF8String],
minimumCStringLength)) == 0) {
if (_s->cStringLength > otherCStringLength)
return OF_ORDERED_DESCENDING;
if (_s->cStringLength < otherCStringLength)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (compare > 0)
return OF_ORDERED_DESCENDING;
else
|
︙ | | | ︙ | |
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
|
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherCString = [otherString UTF8String];
otherCStringLength = [otherString UTF8StringLength];
if (!s->isUTF8) {
minimumCStringLength = (s->cStringLength > otherCStringLength
? otherCStringLength : s->cStringLength);
if ((compare = memcasecmp(s->cString, otherCString,
minimumCStringLength)) == 0) {
if (s->cStringLength > otherCStringLength)
return OF_ORDERED_DESCENDING;
if (s->cStringLength < otherCStringLength)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (compare > 0)
return OF_ORDERED_DESCENDING;
else
return OF_ORDERED_ASCENDING;
}
i = j = 0;
while (i < s->cStringLength && j < otherCStringLength) {
of_unichar_t c1, c2;
size_t l1, l2;
l1 = of_string_utf8_decode(s->cString + i,
s->cStringLength - i, &c1);
l2 = of_string_utf8_decode(otherCString + j,
otherCStringLength - j, &c2);
if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
|
|
|
|
|
|
|
|
|
|
|
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
|
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherCString = [otherString UTF8String];
otherCStringLength = [otherString UTF8StringLength];
if (!_s->isUTF8) {
minimumCStringLength = (_s->cStringLength > otherCStringLength
? otherCStringLength : _s->cStringLength);
if ((compare = memcasecmp(_s->cString, otherCString,
minimumCStringLength)) == 0) {
if (_s->cStringLength > otherCStringLength)
return OF_ORDERED_DESCENDING;
if (_s->cStringLength < otherCStringLength)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
if (compare > 0)
return OF_ORDERED_DESCENDING;
else
return OF_ORDERED_ASCENDING;
}
i = j = 0;
while (i < _s->cStringLength && j < otherCStringLength) {
of_unichar_t c1, c2;
size_t l1, l2;
l1 = of_string_utf8_decode(_s->cString + i,
_s->cStringLength - i, &c1);
l2 = of_string_utf8_decode(otherCString + j,
otherCStringLength - j, &c2);
if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
|
︙ | | | ︙ | |
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
|
if (c1 < c2)
return OF_ORDERED_ASCENDING;
i += l1;
j += l2;
}
if (s->cStringLength - i > otherCStringLength - j)
return OF_ORDERED_DESCENDING;
else if (s->cStringLength - i < otherCStringLength - j)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
- (uint32_t)hash
{
size_t i;
uint32_t hash;
if (s->hashed)
return s->hash;
OF_HASH_INIT(hash);
for (i = 0; i < s->cStringLength; i++) {
of_unichar_t c;
size_t length;
if ((length = of_string_utf8_decode(s->cString + i,
s->cStringLength - i, &c)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
OF_HASH_ADD(hash, (c & 0xFF0000) >> 16);
OF_HASH_ADD(hash, (c & 0x00FF00) >> 8);
OF_HASH_ADD(hash, c & 0x0000FF);
i += length - 1;
}
OF_HASH_FINALIZE(hash);
s->hash = hash;
s->hashed = YES;
return hash;
}
- (of_unichar_t)characterAtIndex: (size_t)index
{
of_unichar_t character;
if (index >= s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (!s->isUTF8)
return s->cString[index];
index = of_string_utf8_get_position(s->cString, index,
s->cStringLength);
if (!of_string_utf8_decode(s->cString + index, s->cStringLength - index,
&character))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
return character;
}
- (void)getCharacters: (of_unichar_t*)buffer
inRange: (of_range_t)range
{
/* TODO: Could be slightly optimized */
void *pool = objc_autoreleasePoolPush();
const of_unichar_t *characters = [self characters];
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memcpy(buffer, characters + range.location,
range.length * sizeof(of_unichar_t));
objc_autoreleasePoolPop(pool);
}
- (of_range_t)rangeOfString: (OFString*)string
options: (int)options
range: (of_range_t)range
{
const char *cString = [string UTF8String];
size_t i, cStringLength = [string UTF8StringLength];
size_t rangeLocation, rangeLength;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (s->isUTF8) {
rangeLocation = of_string_utf8_get_position(
s->cString, range.location, s->cStringLength);
rangeLength = of_string_utf8_get_position(
s->cString + rangeLocation, range.length,
s->cStringLength - rangeLocation);
} else {
rangeLocation = range.location;
rangeLength = range.length;
}
if (cStringLength == 0)
return of_range(0, 0);
if (cStringLength > rangeLength)
return of_range(OF_NOT_FOUND, 0);
if (options & OF_STRING_SEARCH_BACKWARDS) {
for (i = rangeLength - cStringLength;; i--) {
if (!memcmp(s->cString + rangeLocation + i, cString,
cStringLength)) {
range.location += of_string_utf8_get_index(
s->cString + rangeLocation, i);
range.length = [string length];
return range;
}
/* Did not match and we're at the last char */
if (i == 0)
return of_range(OF_NOT_FOUND, 0);
}
} else {
for (i = 0; i <= rangeLength - cStringLength; i++) {
if (!memcmp(s->cString + rangeLocation + i, cString,
cStringLength)) {
range.location += of_string_utf8_get_index(
s->cString + rangeLocation, i);
range.length = [string length];
return range;
}
}
}
return of_range(OF_NOT_FOUND, 0);
}
- (BOOL)containsString: (OFString*)string
{
const char *cString = [string UTF8String];
size_t i, cStringLength = [string UTF8StringLength];
if (cStringLength == 0)
return YES;
if (cStringLength > s->cStringLength)
return NO;
for (i = 0; i <= s->cStringLength - cStringLength; i++)
if (!memcmp(s->cString + i, cString, cStringLength))
return YES;
return NO;
}
- (OFString*)substringWithRange: (of_range_t)range
{
size_t start = range.location;
size_t end = range.location + range.length;
if (range.length > SIZE_MAX - range.location || end > s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (s->isUTF8) {
start = of_string_utf8_get_position(s->cString, start,
s->cStringLength);
end = of_string_utf8_get_position(s->cString, end,
s->cStringLength);
}
return [OFString stringWithUTF8String: s->cString + start
length: end - start];
}
- (BOOL)hasPrefix: (OFString*)prefix
{
size_t cStringLength = [prefix UTF8StringLength];
if (cStringLength > s->cStringLength)
return NO;
return !memcmp(s->cString, [prefix UTF8String], cStringLength);
}
- (BOOL)hasSuffix: (OFString*)suffix
{
size_t cStringLength = [suffix UTF8StringLength];
if (cStringLength > s->cStringLength)
return NO;
return !memcmp(s->cString + (s->cStringLength - cStringLength),
[suffix UTF8String], cStringLength);
}
- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
options: (int)options
{
void *pool;
OFMutableArray *array;
const char *cString = [delimiter UTF8String];
size_t cStringLength = [delimiter UTF8StringLength];
BOOL skipEmpty = (options & OF_STRING_SKIP_EMPTY);
size_t i, last;
OFString *component;
array = [OFMutableArray array];
pool = objc_autoreleasePoolPush();
if (cStringLength > s->cStringLength) {
[array addObject: [[self copy] autorelease]];
objc_autoreleasePoolPop(pool);
return array;
}
for (i = 0, last = 0; i <= s->cStringLength - cStringLength; i++) {
if (memcmp(s->cString + i, cString, cStringLength))
continue;
component = [OFString stringWithUTF8String: s->cString + last
length: i - last];
if (!skipEmpty || [component length] > 0)
[array addObject: component];
i += cStringLength - 1;
last = i + 1;
}
component = [OFString stringWithUTF8String: s->cString + last];
if (!skipEmpty || [component length] > 0)
[array addObject: component];
[array makeImmutable];
objc_autoreleasePoolPop(pool);
return array;
}
- (OFArray*)pathComponents
{
OFMutableArray *ret;
void *pool;
size_t i, last = 0, pathCStringLength = s->cStringLength;
ret = [OFMutableArray array];
if (pathCStringLength == 0)
return ret;
pool = objc_autoreleasePoolPush();
#ifndef _WIN32
if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (s->cString[pathCStringLength - 1] == '/' ||
s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
for (i = 0; i < pathCStringLength; i++) {
#ifndef _WIN32
if (s->cString[i] == OF_PATH_DELIMITER) {
#else
if (s->cString[i] == '/' || s->cString[i] == '\\') {
#endif
[ret addObject:
[OFString stringWithUTF8String: s->cString + last
length: i - last]];
last = i + 1;
}
}
[ret addObject: [OFString stringWithUTF8String: s->cString + last
length: i - last]];
[ret makeImmutable];
objc_autoreleasePoolPop(pool);
return ret;
}
- (OFString*)lastPathComponent
{
size_t pathCStringLength = s->cStringLength;
ssize_t i;
if (pathCStringLength == 0)
return @"";
#ifndef _WIN32
if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (s->cString[pathCStringLength - 1] == '/' ||
s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
for (i = pathCStringLength - 1; i >= 0; i--) {
#ifndef _WIN32
if (s->cString[i] == OF_PATH_DELIMITER) {
#else
if (s->cString[i] == '/' || s->cString[i] == '\\') {
#endif
i++;
break;
}
}
/*
* Only one component, but the trailing delimiter might have been
* removed, so return a new string anyway.
*/
if (i < 0)
i = 0;
return [OFString stringWithUTF8String: s->cString + i
length: pathCStringLength - i];
}
- (OFString*)stringByDeletingLastPathComponent
{
size_t i, pathCStringLength = s->cStringLength;
if (pathCStringLength == 0)
return @"";
#ifndef _WIN32
if (s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (s->cString[pathCStringLength - 1] == '/' ||
s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
if (pathCStringLength == 0)
return [OFString stringWithUTF8String: s->cString
length: 1];
for (i = pathCStringLength - 1; i >= 1; i--)
#ifndef _WIN32
if (s->cString[i] == OF_PATH_DELIMITER)
#else
if (s->cString[i] == '/' || s->cString[i] == '\\')
#endif
return [OFString stringWithUTF8String: s->cString
length: i];
#ifndef _WIN32
if (s->cString[0] == OF_PATH_DELIMITER)
#else
if (s->cString[0] == '/' || s->cString[0] == '\\')
#endif
return [OFString stringWithUTF8String: s->cString
length: 1];
return @".";
}
- (const of_unichar_t*)characters
{
OFObject *object = [[[OFObject alloc] init] autorelease];
of_unichar_t *ret;
size_t i, j;
ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
count: s->length];
i = j = 0;
while (i < s->cStringLength) {
of_unichar_t c;
size_t cLen;
cLen = of_string_utf8_decode(s->cString + i,
s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
ret[j++] = c;
i += cLen;
}
return ret;
}
- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
OFObject *object = [[[OFObject alloc] init] autorelease];
of_char32_t *ret;
size_t i, j;
ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
count: s->length + 1];
i = j = 0;
while (i < s->cStringLength) {
of_unichar_t c;
size_t cLen;
cLen = of_string_utf8_decode(s->cString + i,
s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
if (byteOrder != OF_BYTE_ORDER_NATIVE)
ret[j++] = OF_BSWAP32(c);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
|
if (c1 < c2)
return OF_ORDERED_ASCENDING;
i += l1;
j += l2;
}
if (_s->cStringLength - i > otherCStringLength - j)
return OF_ORDERED_DESCENDING;
else if (_s->cStringLength - i < otherCStringLength - j)
return OF_ORDERED_ASCENDING;
return OF_ORDERED_SAME;
}
- (uint32_t)hash
{
size_t i;
uint32_t hash;
if (_s->hashed)
return _s->hash;
OF_HASH_INIT(hash);
for (i = 0; i < _s->cStringLength; i++) {
of_unichar_t c;
size_t length;
if ((length = of_string_utf8_decode(_s->cString + i,
_s->cStringLength - i, &c)) == 0)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
OF_HASH_ADD(hash, (c & 0xFF0000) >> 16);
OF_HASH_ADD(hash, (c & 0x00FF00) >> 8);
OF_HASH_ADD(hash, c & 0x0000FF);
i += length - 1;
}
OF_HASH_FINALIZE(hash);
_s->hash = hash;
_s->hashed = YES;
return hash;
}
- (of_unichar_t)characterAtIndex: (size_t)index
{
of_unichar_t character;
if (index >= _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (!_s->isUTF8)
return _s->cString[index];
index = of_string_utf8_get_position(_s->cString, index,
_s->cStringLength);
if (!of_string_utf8_decode(_s->cString + index,
_s->cStringLength - index, &character))
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
return character;
}
- (void)getCharacters: (of_unichar_t*)buffer
inRange: (of_range_t)range
{
/* TODO: Could be slightly optimized */
void *pool = objc_autoreleasePoolPush();
const of_unichar_t *characters = [self characters];
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
memcpy(buffer, characters + range.location,
range.length * sizeof(of_unichar_t));
objc_autoreleasePoolPop(pool);
}
- (of_range_t)rangeOfString: (OFString*)string
options: (int)options
range: (of_range_t)range
{
const char *cString = [string UTF8String];
size_t i, cStringLength = [string UTF8StringLength];
size_t rangeLocation, rangeLength;
if (range.length > SIZE_MAX - range.location ||
range.location + range.length > _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (_s->isUTF8) {
rangeLocation = of_string_utf8_get_position(
_s->cString, range.location, _s->cStringLength);
rangeLength = of_string_utf8_get_position(
_s->cString + rangeLocation, range.length,
_s->cStringLength - rangeLocation);
} else {
rangeLocation = range.location;
rangeLength = range.length;
}
if (cStringLength == 0)
return of_range(0, 0);
if (cStringLength > rangeLength)
return of_range(OF_NOT_FOUND, 0);
if (options & OF_STRING_SEARCH_BACKWARDS) {
for (i = rangeLength - cStringLength;; i--) {
if (!memcmp(_s->cString + rangeLocation + i, cString,
cStringLength)) {
range.location += of_string_utf8_get_index(
_s->cString + rangeLocation, i);
range.length = [string length];
return range;
}
/* Did not match and we're at the last char */
if (i == 0)
return of_range(OF_NOT_FOUND, 0);
}
} else {
for (i = 0; i <= rangeLength - cStringLength; i++) {
if (!memcmp(_s->cString + rangeLocation + i, cString,
cStringLength)) {
range.location += of_string_utf8_get_index(
_s->cString + rangeLocation, i);
range.length = [string length];
return range;
}
}
}
return of_range(OF_NOT_FOUND, 0);
}
- (BOOL)containsString: (OFString*)string
{
const char *cString = [string UTF8String];
size_t i, cStringLength = [string UTF8StringLength];
if (cStringLength == 0)
return YES;
if (cStringLength > _s->cStringLength)
return NO;
for (i = 0; i <= _s->cStringLength - cStringLength; i++)
if (!memcmp(_s->cString + i, cString, cStringLength))
return YES;
return NO;
}
- (OFString*)substringWithRange: (of_range_t)range
{
size_t start = range.location;
size_t end = range.location + range.length;
if (range.length > SIZE_MAX - range.location || end > _s->length)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
if (_s->isUTF8) {
start = of_string_utf8_get_position(_s->cString, start,
_s->cStringLength);
end = of_string_utf8_get_position(_s->cString, end,
_s->cStringLength);
}
return [OFString stringWithUTF8String: _s->cString + start
length: end - start];
}
- (BOOL)hasPrefix: (OFString*)prefix
{
size_t cStringLength = [prefix UTF8StringLength];
if (cStringLength > _s->cStringLength)
return NO;
return !memcmp(_s->cString, [prefix UTF8String], cStringLength);
}
- (BOOL)hasSuffix: (OFString*)suffix
{
size_t cStringLength = [suffix UTF8StringLength];
if (cStringLength > _s->cStringLength)
return NO;
return !memcmp(_s->cString + (_s->cStringLength - cStringLength),
[suffix UTF8String], cStringLength);
}
- (OFArray*)componentsSeparatedByString: (OFString*)delimiter
options: (int)options
{
void *pool;
OFMutableArray *array;
const char *cString = [delimiter UTF8String];
size_t cStringLength = [delimiter UTF8StringLength];
BOOL skipEmpty = (options & OF_STRING_SKIP_EMPTY);
size_t i, last;
OFString *component;
array = [OFMutableArray array];
pool = objc_autoreleasePoolPush();
if (cStringLength > _s->cStringLength) {
[array addObject: [[self copy] autorelease]];
objc_autoreleasePoolPop(pool);
return array;
}
for (i = 0, last = 0; i <= _s->cStringLength - cStringLength; i++) {
if (memcmp(_s->cString + i, cString, cStringLength))
continue;
component = [OFString stringWithUTF8String: _s->cString + last
length: i - last];
if (!skipEmpty || [component length] > 0)
[array addObject: component];
i += cStringLength - 1;
last = i + 1;
}
component = [OFString stringWithUTF8String: _s->cString + last];
if (!skipEmpty || [component length] > 0)
[array addObject: component];
[array makeImmutable];
objc_autoreleasePoolPop(pool);
return array;
}
- (OFArray*)pathComponents
{
OFMutableArray *ret;
void *pool;
size_t i, last = 0, pathCStringLength = _s->cStringLength;
ret = [OFMutableArray array];
if (pathCStringLength == 0)
return ret;
pool = objc_autoreleasePoolPush();
#ifndef _WIN32
if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (_s->cString[pathCStringLength - 1] == '/' ||
_s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
for (i = 0; i < pathCStringLength; i++) {
#ifndef _WIN32
if (_s->cString[i] == OF_PATH_DELIMITER) {
#else
if (_s->cString[i] == '/' || _s->cString[i] == '\\') {
#endif
[ret addObject:
[OFString stringWithUTF8String: _s->cString + last
length: i - last]];
last = i + 1;
}
}
[ret addObject: [OFString stringWithUTF8String: _s->cString + last
length: i - last]];
[ret makeImmutable];
objc_autoreleasePoolPop(pool);
return ret;
}
- (OFString*)lastPathComponent
{
size_t pathCStringLength = _s->cStringLength;
ssize_t i;
if (pathCStringLength == 0)
return @"";
#ifndef _WIN32
if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (_s->cString[pathCStringLength - 1] == '/' ||
_s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
for (i = pathCStringLength - 1; i >= 0; i--) {
#ifndef _WIN32
if (_s->cString[i] == OF_PATH_DELIMITER) {
#else
if (_s->cString[i] == '/' || _s->cString[i] == '\\') {
#endif
i++;
break;
}
}
/*
* Only one component, but the trailing delimiter might have been
* removed, so return a new string anyway.
*/
if (i < 0)
i = 0;
return [OFString stringWithUTF8String: _s->cString + i
length: pathCStringLength - i];
}
- (OFString*)stringByDeletingLastPathComponent
{
size_t i, pathCStringLength = _s->cStringLength;
if (pathCStringLength == 0)
return @"";
#ifndef _WIN32
if (_s->cString[pathCStringLength - 1] == OF_PATH_DELIMITER)
#else
if (_s->cString[pathCStringLength - 1] == '/' ||
_s->cString[pathCStringLength - 1] == '\\')
#endif
pathCStringLength--;
if (pathCStringLength == 0)
return [OFString stringWithUTF8String: _s->cString
length: 1];
for (i = pathCStringLength - 1; i >= 1; i--)
#ifndef _WIN32
if (_s->cString[i] == OF_PATH_DELIMITER)
#else
if (_s->cString[i] == '/' || _s->cString[i] == '\\')
#endif
return [OFString stringWithUTF8String: _s->cString
length: i];
#ifndef _WIN32
if (_s->cString[0] == OF_PATH_DELIMITER)
#else
if (_s->cString[0] == '/' || _s->cString[0] == '\\')
#endif
return [OFString stringWithUTF8String: _s->cString
length: 1];
return @".";
}
- (const of_unichar_t*)characters
{
OFObject *object = [[[OFObject alloc] init] autorelease];
of_unichar_t *ret;
size_t i, j;
ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
count: _s->length];
i = j = 0;
while (i < _s->cStringLength) {
of_unichar_t c;
size_t cLen;
cLen = of_string_utf8_decode(_s->cString + i,
_s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
ret[j++] = c;
i += cLen;
}
return ret;
}
- (const of_char32_t*)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
OFObject *object = [[[OFObject alloc] init] autorelease];
of_char32_t *ret;
size_t i, j;
ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
count: _s->length + 1];
i = j = 0;
while (i < _s->cStringLength) {
of_unichar_t c;
size_t cLen;
cLen = of_string_utf8_decode(_s->cString + i,
_s->cStringLength - i, &c);
if (cLen == 0 || c > 0x10FFFF)
@throw [OFInvalidEncodingException
exceptionWithClass: [self class]];
if (byteOrder != OF_BYTE_ORDER_NATIVE)
ret[j++] = OF_BSWAP32(c);
|
︙ | | | ︙ | |
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
|
return ret;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
void *pool;
const char *cString = s->cString;
const char *last = cString;
BOOL stop = NO, lastCarriageReturn = NO;
while (!stop && *cString != 0) {
if (lastCarriageReturn && *cString == '\n') {
lastCarriageReturn = NO;
|
|
|
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
|
return ret;
}
#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
void *pool;
const char *cString = _s->cString;
const char *last = cString;
BOOL stop = NO, lastCarriageReturn = NO;
while (!stop && *cString != 0) {
if (lastCarriageReturn && *cString == '\n') {
lastCarriageReturn = NO;
|
︙ | | | ︙ | |
Modified src/OFTCPSocket.h
from [80ab9c568a]
to [99ba0b78fd].
︙ | | | ︙ | |
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
|
* @brief A class which provides functions to create and use TCP sockets.
*
* To connect to a server, create a socket and connect it.
* To create a server, create a socket, bind it and listen on it.
*/
@interface OFTCPSocket: OFStreamSocket
{
BOOL listening;
struct sockaddr_storage *sockAddr;
socklen_t sockAddrLen;
OFString *SOCKS5Host;
uint16_t SOCKS5Port;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isListening) BOOL listening;
@property (copy) OFString *SOCKS5Host;
@property uint16_t SOCKS5Port;
#endif
/*!
* @brief Sets the global SOCKS5 proxy host to use when creating a new socket
*
* @param host The host to use as a SOCKS5 proxy when creating a new socket
*/
+ (void)setSOCKS5Host: (OFString*)host;
/*!
* @brief Returns the host to use as a SOCKS5 proxy when creating a new socket
*
* @return The host to use as a SOCKS5 proxy when creating a new socket
*/
+ (OFString*)SOCKS5Host;
/*!
* @brief Sets the global SOCKS5 proxy port to use when creating a new socket
*
* @param port The port to use as a SOCKS5 proxy when creating a new socket
*/
+ (void)setSOCKS5Port: (uint16_t)port;
/*!
* @brief Returns the port to use as a SOCKS5 proxy when creating a new socket
*
* @return The port to use as a SOCKS5 proxy when creating a new socket
*/
+ (uint16_t)SOCKS5Port;
|
|
|
|
|
|
|
>
|
|
|
|
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
|
* @brief A class which provides functions to create and use TCP sockets.
*
* To connect to a server, create a socket and connect it.
* To create a server, create a socket, bind it and listen on it.
*/
@interface OFTCPSocket: OFStreamSocket
{
BOOL _listening;
struct sockaddr_storage *_sockAddr;
socklen_t _sockAddrLen;
OFString *_SOCKS5Host;
uint16_t _SOCKS5Port;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, getter=isListening) BOOL listening;
@property (copy) OFString *SOCKS5Host;
@property uint16_t SOCKS5Port;
#endif
/*!
* @brief Sets the global SOCKS5 proxy host to use when creating a new socket
*
* @param SOCKS5Host The host to use as a SOCKS5 proxy when creating a new
* socket
*/
+ (void)setSOCKS5Host: (OFString*)SOCKS5Host;
/*!
* @brief Returns the host to use as a SOCKS5 proxy when creating a new socket
*
* @return The host to use as a SOCKS5 proxy when creating a new socket
*/
+ (OFString*)SOCKS5Host;
/*!
* @brief Sets the global SOCKS5 proxy port to use when creating a new socket
*
* @param SOCKS5Port The port to use as a SOCKS5 proxy when creating a new socket
*/
+ (void)setSOCKS5Port: (uint16_t)SOCKS5Port;
/*!
* @brief Returns the port to use as a SOCKS5 proxy when creating a new socket
*
* @return The port to use as a SOCKS5 proxy when creating a new socket
*/
+ (uint16_t)SOCKS5Port;
|
︙ | | | ︙ | |
Modified src/OFTCPSocket.m
from [e3f567d132]
to [742dd6ce2f].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;
#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
OFThread *sourceThread;
OFTCPSocket *sock;
OFString *host;
uint16_t port;
id target;
SEL selector;
# ifdef OF_HAVE_BLOCKS
of_tcpsocket_async_connect_block_t connectBlock;
# endif
OFException *exception;
}
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
target: (id)target
selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
block: (of_tcpsocket_async_connect_block_t)block;
# endif
@end
@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread_
socket: (OFTCPSocket*)sock_
host: (OFString*)host_
port: (uint16_t)port_
target: (id)target_
selector: (SEL)selector_
{
self = [super init];
@try {
sourceThread = [sourceThread_ retain];
sock = [sock_ retain];
host = [host_ copy];
port = port_;
target = [target_ retain];
selector = selector_;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread_
socket: (OFTCPSocket*)sock_
host: (OFString*)host_
port: (uint16_t)port_
block: (of_tcpsocket_async_connect_block_t)block_
{
self = [super init];
@try {
sourceThread = [sourceThread_ retain];
sock = [sock_ retain];
host = [host_ copy];
port = port_;
connectBlock = [block_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
# endif
- (void)dealloc
{
[sourceThread release];
[sock release];
[host release];
[target release];
# ifdef OF_HAVE_BLOCKS
[connectBlock release];
# endif
[exception release];
[super dealloc];
}
- (void)didConnect
{
[self join];
# ifdef OF_HAVE_BLOCKS
if (connectBlock != NULL)
connectBlock(sock, exception);
else {
# endif
void (*func)(id, SEL, OFTCPSocket*, OFException*) =
(void(*)(id, SEL, OFTCPSocket*, OFException*))[target
methodForSelector: selector];
func(target, selector, sock, exception);
# ifdef OF_HAVE_BLOCKS
}
# endif
}
- (id)main
{
void *pool = objc_autoreleasePoolPush();
@try {
[sock connectToHost: host
port: port];
} @catch (OFException *e) {
exception = [[e retain] autorelease];
}
[self performSelector: @selector(didConnect)
onThread: sourceThread
waitUntilDone: NO];
objc_autoreleasePoolPop(pool);
return nil;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
static OFString *defaultSOCKS5Host = nil;
static uint16_t defaultSOCKS5Port = 1080;
#ifdef OF_HAVE_THREADS
@interface OFTCPSocket_ConnectThread: OFThread
{
OFThread *_sourceThread;
OFTCPSocket *_socket;
OFString *_host;
uint16_t _port;
id _target;
SEL _selector;
# ifdef OF_HAVE_BLOCKS
of_tcpsocket_async_connect_block_t _connectBlock;
# endif
OFException *_exception;
}
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
target: (id)target
selector: (SEL)selector;
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
block: (of_tcpsocket_async_connect_block_t)block;
# endif
@end
@implementation OFTCPSocket_ConnectThread
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
target: (id)target
selector: (SEL)selector
{
self = [super init];
@try {
_sourceThread = [sourceThread retain];
_socket = [socket retain];
_host = [host copy];
_port = port;
_target = [target retain];
_selector = selector;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
# ifdef OF_HAVE_BLOCKS
- initWithSourceThread: (OFThread*)sourceThread
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
block: (of_tcpsocket_async_connect_block_t)block
{
self = [super init];
@try {
_sourceThread = [sourceThread retain];
_socket = [socket retain];
_host = [host copy];
_port = port;
_connectBlock = [block copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
# endif
- (void)dealloc
{
[_sourceThread release];
[_socket release];
[_host release];
[_target release];
# ifdef OF_HAVE_BLOCKS
[_connectBlock release];
# endif
[_exception release];
[super dealloc];
}
- (void)didConnect
{
[self join];
# ifdef OF_HAVE_BLOCKS
if (_connectBlock != NULL)
_connectBlock(_socket, _exception);
else {
# endif
void (*func)(id, SEL, OFTCPSocket*, OFException*) =
(void(*)(id, SEL, OFTCPSocket*, OFException*))[_target
methodForSelector: _selector];
func(_target, _selector, _socket, _exception);
# ifdef OF_HAVE_BLOCKS
}
# endif
}
- (id)main
{
void *pool = objc_autoreleasePoolPush();
@try {
[_socket connectToHost: _host
port: _port];
} @catch (OFException *e) {
_exception = [[e retain] autorelease];
}
[self performSelector: @selector(didConnect)
onThread: _sourceThread
waitUntilDone: NO];
objc_autoreleasePoolPop(pool);
return nil;
}
@end
|
︙ | | | ︙ | |
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
}
- init
{
self = [super init];
@try {
sock = INVALID_SOCKET;
sockAddr = NULL;
SOCKS5Host = [defaultSOCKS5Host copy];
SOCKS5Port = defaultSOCKS5Port;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[SOCKS5Host release];
[super dealloc];
}
- (void)setSOCKS5Host: (OFString*)host
{
OF_SETTER(SOCKS5Host, host, YES, 1)
}
- (OFString*)SOCKS5Host
{
OF_GETTER(SOCKS5Host, YES)
}
- (void)setSOCKS5Port: (uint16_t)port
{
SOCKS5Port = port;
}
- (uint16_t)SOCKS5Port
{
return SOCKS5Port;
}
- (void)connectToHost: (OFString*)host
port: (uint16_t)port
{
OFString *destinationHost = host;
uint16_t destinationPort = port;
if (sock != INVALID_SOCKET)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: self];
if (SOCKS5Host != nil) {
/* Connect to the SOCKS5 proxy instead */
host = SOCKS5Host;
port = SOCKS5Port;
}
#ifdef HAVE_THREADSAFE_GETADDRINFO
struct addrinfo hints, *res, *res0;
char portCString[7];
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
snprintf(portCString, 7, "%" PRIu16, port);
if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
portCString, &hints, &res0))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]
socket: self
host: host];
for (res = res0; res != NULL; res = res->ai_next) {
if ((sock = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) == INVALID_SOCKET)
continue;
if (connect(sock, res->ai_addr, res->ai_addrlen) == -1) {
close(sock);
sock = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(res0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
}
- init
{
self = [super init];
@try {
_socket = INVALID_SOCKET;
_sockAddr = NULL;
_SOCKS5Host = [defaultSOCKS5Host copy];
_SOCKS5Port = defaultSOCKS5Port;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_SOCKS5Host release];
[super dealloc];
}
- (void)setSOCKS5Host: (OFString*)SOCKS5Host
{
OF_SETTER(_SOCKS5Host, SOCKS5Host, YES, 1)
}
- (OFString*)SOCKS5Host
{
OF_GETTER(_SOCKS5Host, YES)
}
- (void)setSOCKS5Port: (uint16_t)SOCKS5Port
{
_SOCKS5Port = SOCKS5Port;
}
- (uint16_t)SOCKS5Port
{
return _SOCKS5Port;
}
- (void)connectToHost: (OFString*)host
port: (uint16_t)port
{
OFString *destinationHost = host;
uint16_t destinationPort = port;
if (_socket != INVALID_SOCKET)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: self];
if (_SOCKS5Host != nil) {
/* Connect to the SOCKS5 proxy instead */
host = _SOCKS5Host;
port = _SOCKS5Port;
}
#ifdef HAVE_THREADSAFE_GETADDRINFO
struct addrinfo hints, *res, *res0;
char portCString[7];
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
snprintf(portCString, 7, "%" PRIu16, port);
if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
portCString, &hints, &res0))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]
socket: self
host: host];
for (res = res0; res != NULL; res = res->ai_next) {
if ((_socket = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) == INVALID_SOCKET)
continue;
if (connect(_socket, res->ai_addr, res->ai_addrlen) == -1) {
close(_socket);
_socket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(res0);
|
︙ | | | ︙ | |
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = OF_BSWAP16_IF_LE(port);
if (he->h_addrtype != AF_INET ||
(sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_HAVE_THREADS
[addrlist release];
[mutex unlock];
# endif
@throw [OFConnectionFailedException
exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
# ifdef OF_HAVE_THREADS
@try {
for (ip = he->h_addr_list; *ip != NULL; ip++)
[addrlist addItem: ip];
|
|
|
|
|
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = OF_BSWAP16_IF_LE(port);
if (he->h_addrtype != AF_INET ||
(_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
# ifdef OF_HAVE_THREADS
[addrlist release];
[mutex unlock];
# endif
@throw [OFConnectionFailedException
exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
# ifdef OF_HAVE_THREADS
@try {
for (ip = he->h_addr_list; *ip != NULL; ip++)
[addrlist addItem: ip];
|
︙ | | | ︙ | |
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
|
for (ip = [addrlist items]; *ip != NULL; ip++) {
# else
for (ip = he->h_addr_list; *ip != NULL; ip++) {
# endif
memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1)
continue;
connected = YES;
break;
}
# ifdef OF_HAVE_THREADS
[addrlist release];
# endif
if (!connected) {
close(sock);
sock = INVALID_SOCKET;
}
#endif
if (sock == INVALID_SOCKET)
@throw [OFConnectionFailedException
exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (SOCKS5Host != nil)
[self OF_SOCKS5ConnectToHost: destinationHost
port: destinationPort];
}
#ifdef OF_HAVE_THREADS
- (void)asyncConnectToHost: (OFString*)host
port: (uint16_t)port
|
>
|
|
|
|
|
|
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
|
for (ip = [addrlist items]; *ip != NULL; ip++) {
# else
for (ip = he->h_addr_list; *ip != NULL; ip++) {
# endif
memcpy(&addr.sin_addr.s_addr, *ip, he->h_length);
if (connect(_socket, (struct sockaddr*)&addr,
sizeof(addr)) == -1)
continue;
connected = YES;
break;
}
# ifdef OF_HAVE_THREADS
[addrlist release];
# endif
if (!connected) {
close(_socket);
_socket = INVALID_SOCKET;
}
#endif
if (_socket == INVALID_SOCKET)
@throw [OFConnectionFailedException
exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (_SOCKS5Host != nil)
[self OF_SOCKS5ConnectToHost: destinationHost
port: destinationPort];
}
#ifdef OF_HAVE_THREADS
- (void)asyncConnectToHost: (OFString*)host
port: (uint16_t)port
|
︙ | | | ︙ | |
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
|
union {
struct sockaddr_storage storage;
struct sockaddr_in in;
struct sockaddr_in6 in6;
} addr;
socklen_t addrLen;
if (sock != INVALID_SOCKET)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: self];
if (SOCKS5Host != nil)
@throw [OFNotImplementedException
exceptionWithClass: [self class]
selector: _cmd];
#ifdef HAVE_THREADSAFE_GETADDRINFO
struct addrinfo hints, *res;
char portCString[7];
|
|
|
|
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
union {
struct sockaddr_storage storage;
struct sockaddr_in in;
struct sockaddr_in6 in6;
} addr;
socklen_t addrLen;
if (_socket != INVALID_SOCKET)
@throw [OFAlreadyConnectedException
exceptionWithClass: [self class]
socket: self];
if (_SOCKS5Host != nil)
@throw [OFNotImplementedException
exceptionWithClass: [self class]
selector: _cmd];
#ifdef HAVE_THREADSAFE_GETADDRINFO
struct addrinfo hints, *res;
char portCString[7];
|
︙ | | | ︙ | |
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
|
if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
portCString, &hints, &res))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]
socket: self
host: host];
if ((sock = socket(res->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
sizeof(one)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
freeaddrinfo(res);
close(sock);
sock = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
freeaddrinfo(res);
|
|
>
|
|
|
|
|
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
|
if (getaddrinfo([host cStringWithEncoding: OF_STRING_ENCODING_NATIVE],
portCString, &hints, &res))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]
socket: self
host: host];
if ((_socket = socket(res->ai_family, SOCK_STREAM,
0)) == INVALID_SOCKET)
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
sizeof(one)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
if (bind(_socket, res->ai_addr, res->ai_addrlen) == -1) {
freeaddrinfo(res);
close(_socket);
_socket = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
freeaddrinfo(res);
|
︙ | | | ︙ | |
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
|
}
memcpy(&addr.in.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
# ifdef OF_HAVE_THREADS
[mutex unlock];
# endif
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
sizeof(one)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
if (bind(sock, (struct sockaddr*)&addr.in, sizeof(addr.in)) == -1) {
close(sock);
sock = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
#endif
if (port > 0)
return port;
addrLen = sizeof(addr.storage);
if (getsockname(sock, (struct sockaddr*)&addr, &addrLen)) {
close(sock);
sock = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
if (addr.storage.ss_family == AF_INET)
return OF_BSWAP16_IF_LE(addr.in.sin_port);
if (addr.storage.ss_family == AF_INET6)
return OF_BSWAP16_IF_LE(addr.in6.sin6_port);
close(sock);
sock = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
- (void)listenWithBackLog: (int)backLog
{
if (sock == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (listen(sock, backLog) == -1)
@throw [OFListenFailedException exceptionWithClass: [self class]
socket: self
backLog: backLog];
listening = YES;
}
- (void)listen
{
[self listenWithBackLog: SOMAXCONN];
}
- (OFTCPSocket*)accept
{
OFTCPSocket *newSocket;
struct sockaddr_storage *addr;
socklen_t addrLen;
int newSock;
newSocket = [[[[self class] alloc] init] autorelease];
addrLen = sizeof(*addr);
addr = [newSocket allocMemoryWithSize: addrLen];
if ((newSock = accept(sock, (struct sockaddr*)addr,
&addrLen)) == INVALID_SOCKET)
@throw [OFAcceptFailedException exceptionWithClass: [self class]
socket: self];
newSocket->sock = newSock;
newSocket->sockAddr = addr;
newSocket->sockAddrLen = addrLen;
return newSocket;
}
- (void)asyncAcceptWithTarget: (id)target
selector: (SEL)selector
{
[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
target: target
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
|
}
memcpy(&addr.in.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
# ifdef OF_HAVE_THREADS
[mutex unlock];
# endif
if ((_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
if (setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&one,
sizeof(one)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
if (bind(_socket, (struct sockaddr*)&addr.in, sizeof(addr.in)) == -1) {
close(_socket);
_socket = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
#endif
if (port > 0)
return port;
addrLen = sizeof(addr.storage);
if (getsockname(_socket, (struct sockaddr*)&addr, &addrLen)) {
close(_socket);
_socket = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
if (addr.storage.ss_family == AF_INET)
return OF_BSWAP16_IF_LE(addr.in.sin_port);
if (addr.storage.ss_family == AF_INET6)
return OF_BSWAP16_IF_LE(addr.in6.sin6_port);
close(_socket);
_socket = INVALID_SOCKET;
@throw [OFBindFailedException exceptionWithClass: [self class]
socket: self
host: host
port: port];
}
- (void)listenWithBackLog: (int)backLog
{
if (_socket == INVALID_SOCKET)
@throw [OFNotConnectedException exceptionWithClass: [self class]
socket: self];
if (listen(_socket, backLog) == -1)
@throw [OFListenFailedException exceptionWithClass: [self class]
socket: self
backLog: backLog];
_listening = YES;
}
- (void)listen
{
[self listenWithBackLog: SOMAXCONN];
}
- (OFTCPSocket*)accept
{
OFTCPSocket *client;
struct sockaddr_storage *addr;
socklen_t addrLen;
int socket;
client = [[[[self class] alloc] init] autorelease];
addrLen = sizeof(*addr);
addr = [client allocMemoryWithSize: addrLen];
if ((socket = accept(_socket, (struct sockaddr*)addr,
&addrLen)) == INVALID_SOCKET)
@throw [OFAcceptFailedException exceptionWithClass: [self class]
socket: self];
client->_socket = socket;
client->_sockAddr = addr;
client->_sockAddrLen = addrLen;
return client;
}
- (void)asyncAcceptWithTarget: (id)target
selector: (SEL)selector
{
[OFRunLoop OF_addAsyncAcceptForTCPSocket: self
target: target
|
︙ | | | ︙ | |
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
|
}
#endif
- (void)setKeepAlivesEnabled: (BOOL)enable
{
int v = enable;
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
}
- (OFString*)remoteAddress
{
char *host;
if (sockAddr == NULL || sockAddrLen == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
#ifdef HAVE_THREADSAFE_GETADDRINFO
host = [self allocMemoryWithSize: NI_MAXHOST];
@try {
if (getnameinfo((struct sockaddr*)sockAddr, sockAddrLen, host,
NI_MAXHOST, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]];
return [OFString stringWithCString: host
encoding: OF_STRING_ENCODING_NATIVE];
} @finally {
[self freeMemory: host];
}
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
host = inet_ntoa(((struct sockaddr_in*)sockAddr)->sin_addr);
if (host == NULL)
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]];
return [OFString stringWithCString: host
encoding: OF_STRING_ENCODING_NATIVE];
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
}
# endif
#endif
/* Get rid of a warning, never reached anyway */
assert(0);
}
- (BOOL)isListening
{
return listening;
}
- (void)close
{
[super close];
listening = NO;
[self freeMemory: sockAddr];
sockAddr = NULL;
sockAddrLen = 0;
}
@end
|
|
|
|
|
|
|
|
|
|
|
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
|
}
#endif
- (void)setKeepAlivesEnabled: (BOOL)enable
{
int v = enable;
if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&v, sizeof(v)))
@throw [OFSetOptionFailedException
exceptionWithClass: [self class]
stream: self];
}
- (OFString*)remoteAddress
{
char *host;
if (_sockAddr == NULL || _sockAddrLen == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
#ifdef HAVE_THREADSAFE_GETADDRINFO
host = [self allocMemoryWithSize: NI_MAXHOST];
@try {
if (getnameinfo((struct sockaddr*)_sockAddr, _sockAddrLen, host,
NI_MAXHOST, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV))
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]];
return [OFString stringWithCString: host
encoding: OF_STRING_ENCODING_NATIVE];
} @finally {
[self freeMemory: host];
}
#else
# ifdef OF_HAVE_THREADS
[mutex lock];
@try {
# endif
host = inet_ntoa(((struct sockaddr_in*)_sockAddr)->sin_addr);
if (host == NULL)
@throw [OFAddressTranslationFailedException
exceptionWithClass: [self class]];
return [OFString stringWithCString: host
encoding: OF_STRING_ENCODING_NATIVE];
# ifdef OF_HAVE_THREADS
} @finally {
[mutex unlock];
}
# endif
#endif
/* Get rid of a warning, never reached anyway */
assert(0);
}
- (BOOL)isListening
{
return _listening;
}
- (void)close
{
[super close];
_listening = NO;
[self freeMemory: _sockAddr];
_sockAddr = NULL;
_sockAddrLen = 0;
}
@end
|
Modified src/OFTLSKey.h
from [e53bfd8cf7]
to [9ad9a41960].
︙ | | | ︙ | |
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/*!
* @brief A class for Thread Local Storage keys.
*/
@interface OFTLSKey: OFObject
{
@public
of_tlskey_t key;
@protected
void (*destructor)(id);
of_list_object_t *listObject;
BOOL initialized;
}
/*!
* @brief Creates a new Thread Local Storage key
*
* @return A new, autoreleased Thread Local Storage key
*/
|
|
|
|
|
|
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/*!
* @brief A class for Thread Local Storage keys.
*/
@interface OFTLSKey: OFObject
{
@public
of_tlskey_t _key;
@protected
void (*_destructor)(id);
of_list_object_t *_listObject;
BOOL _initialized;
}
/*!
* @brief Creates a new Thread Local Storage key
*
* @return A new, autoreleased Thread Local Storage key
*/
|
︙ | | | ︙ | |
Modified src/OFTLSKey.m
from [a1e7ea9f8c]
to [90e1fd67d0].
︙ | | | ︙ | |
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
|
of_list_object_t *iter;
@synchronized (TLSKeys) {
for (iter = [TLSKeys firstListObject]; iter != NULL;
iter = iter->next) {
OFTLSKey *key = (OFTLSKey*)iter->object;
if (key->destructor != NULL)
key->destructor(iter->object);
}
}
}
- init
{
self = [super init];
@try {
if (!of_tlskey_new(&key))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
initialized = YES;
@synchronized (TLSKeys) {
listObject = [TLSKeys appendObject: self];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithDestructor: (void(*)(id))destructor_
{
self = [self init];
destructor = destructor_;
return self;
}
- (void)dealloc
{
if (destructor != NULL)
destructor(self);
if (initialized)
of_tlskey_free(key);
/* In case we called [self release] in init */
if (listObject != NULL) {
@synchronized (TLSKeys) {
[TLSKeys removeListObject: listObject];
}
}
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
>
|
|
<
|
|
>
|
|
|
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
|
of_list_object_t *iter;
@synchronized (TLSKeys) {
for (iter = [TLSKeys firstListObject]; iter != NULL;
iter = iter->next) {
OFTLSKey *key = (OFTLSKey*)iter->object;
if (key->_destructor != NULL)
key->_destructor(iter->object);
}
}
}
- init
{
self = [super init];
@try {
if (!of_tlskey_new(&_key))
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
_initialized = YES;
@synchronized (TLSKeys) {
_listObject = [TLSKeys appendObject: self];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithDestructor: (void(*)(id))destructor
{
self = [self init];
_destructor = destructor;
return self;
}
- (void)dealloc
{
if (_initialized) {
if (_destructor != NULL)
_destructor(self);
of_tlskey_free(_key);
}
/* In case we called [self release] in init */
if (_listObject != NULL) {
@synchronized (TLSKeys) {
[TLSKeys removeListObject: _listObject];
}
}
[super dealloc];
}
@end
|
Modified src/OFThread.h
from [daf9be21c3]
to [abb9dc92a6].
︙ | | | ︙ | |
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
|
@interface OFThread: OFObject <OFCopying>
{
#ifdef OF_THREAD_M
@public
#else
@private
#endif
of_thread_t thread;
enum {
OF_THREAD_NOT_RUNNING,
OF_THREAD_RUNNING,
OF_THREAD_WAITING_FOR_JOIN
} running;
#ifdef OF_HAVE_BLOCKS
of_thread_block_t block;
#endif
id returnValue;
OFRunLoop *runLoop;
OFString *name;
}
#ifdef OF_HAVE_PROPERTIES
# ifdef OF_HAVE_BLOCKS
@property (copy) of_thread_block_t block;
# endif
@property (copy) OFString *name;
|
|
|
|
|
|
|
|
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
|
@interface OFThread: OFObject <OFCopying>
{
#ifdef OF_THREAD_M
@public
#else
@private
#endif
of_thread_t _thread;
enum {
OF_THREAD_NOT_RUNNING,
OF_THREAD_RUNNING,
OF_THREAD_WAITING_FOR_JOIN
} _running;
#ifdef OF_HAVE_BLOCKS
of_thread_block_t _block;
#endif
id _returnValue;
OFRunLoop *_runLoop;
OFString *_name;
}
#ifdef OF_HAVE_PROPERTIES
# ifdef OF_HAVE_BLOCKS
@property (copy) of_thread_block_t block;
# endif
@property (copy) OFString *name;
|
︙ | | | ︙ | |
Modified src/OFThread.m
from [750512444c]
to [d1deb64582].
︙ | | | ︙ | |
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
119
120
121
122
123
124
|
objc_autoreleasePoolPush();
/*
* Nasty workaround for thread implementations which can't return a
* value on join.
*/
#ifdef OF_HAVE_BLOCKS
if (thread->block != NULL)
thread->returnValue = [thread->block() retain];
else
#endif
thread->returnValue = [[thread main] retain];
[thread handleTermination];
thread->running = OF_THREAD_WAITING_FOR_JOIN;
[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
/*
* As the values returned by objc_autoreleasePoolPush() in the ObjFW
* runtime are not actually pointers, but sequential numbers, 0 means
* we pop everything.
*/
objc_autoreleasePoolPop(0);
#endif
[thread release];
return 0;
}
static void
set_thread_name(OFThread *thread)
{
#ifdef __HAIKU__
OFString *name = thread->name;
if (name == nil)
name = [thread className];
rename_thread(get_pthread_thread_id(thread->thread), [name UTF8String]);
#endif
}
@implementation OFThread
#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS)
@synthesize block;
#endif
+ (void)initialize
{
if (self != [OFThread class])
return;
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
|
objc_autoreleasePoolPush();
/*
* Nasty workaround for thread implementations which can't return a
* value on join.
*/
#ifdef OF_HAVE_BLOCKS
if (thread->_block != NULL)
thread->_returnValue = [thread->_block() retain];
else
#endif
thread->_returnValue = [[thread main] retain];
[thread handleTermination];
thread->_running = OF_THREAD_WAITING_FOR_JOIN;
[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
/*
* As the values returned by objc_autoreleasePoolPush() in the ObjFW
* runtime are not actually pointers, but sequential numbers, 0 means
* we pop everything.
*/
objc_autoreleasePoolPop(0);
#endif
[thread release];
return 0;
}
static void
set_thread_name(OFThread *thread)
{
#ifdef __HAIKU__
OFString *name = thread->_name;
if (name == nil)
name = [thread className];
rename_thread(get_pthread_thread_id(thread->thread), [name UTF8String]);
#endif
}
@implementation OFThread
#if defined(OF_HAVE_PROPERTIES) && defined(OF_HAVE_BLOCKS)
@synthesize block = _block;
#endif
+ (void)initialize
{
if (self != [OFThread class])
return;
|
︙ | | | ︙ | |
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
return [[[self alloc] initWithBlock: block] autorelease];
}
#endif
+ (void)setObject: (id)object
forTLSKey: (OFTLSKey*)key
{
id oldObject = of_tlskey_get(key->key);
if (!of_tlskey_set(key->key, [object retain]))
@throw [OFInvalidArgumentException exceptionWithClass: self
selector: _cmd];
[oldObject release];
}
+ (id)objectForTLSKey: (OFTLSKey*)key
{
return [[(id)of_tlskey_get(key->key) retain] autorelease];
}
+ (OFThread*)currentThread
{
return [[(id)of_tlskey_get(threadSelfKey) retain] autorelease];
}
|
|
|
|
|
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
return [[[self alloc] initWithBlock: block] autorelease];
}
#endif
+ (void)setObject: (id)object
forTLSKey: (OFTLSKey*)key
{
id oldObject = of_tlskey_get(key->_key);
if (!of_tlskey_set(key->_key, [object retain]))
@throw [OFInvalidArgumentException exceptionWithClass: self
selector: _cmd];
[oldObject release];
}
+ (id)objectForTLSKey: (OFTLSKey*)key
{
return [[(id)of_tlskey_get(key->_key) retain] autorelease];
}
+ (OFThread*)currentThread
{
return [[(id)of_tlskey_get(threadSelfKey) retain] autorelease];
}
|
︙ | | | ︙ | |
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
}
+ (void)terminateWithObject: (id)object
{
OFThread *thread = of_tlskey_get(threadSelfKey);
if (thread != nil) {
thread->returnValue = [object retain];
[thread handleTermination];
thread->running = OF_THREAD_WAITING_FOR_JOIN;
}
[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
/*
* As the values returned by objc_autoreleasePoolPush() in the ObjFW
* runtime are not actually pointers, but sequential numbers, 0 means
* we pop everything.
*/
objc_autoreleasePoolPop(0);
#endif
[thread release];
of_thread_exit();
}
+ (void)OF_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->thread = of_thread_current();
if (!of_tlskey_set(threadSelfKey, mainThread))
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_block_t)block_
{
self = [super init];
@try {
block = [block_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (id)main
{
[[OFRunLoop currentRunLoop] run];
return nil;
}
- (void)handleTermination
{
OFRunLoop *oldRunLoop = runLoop;
runLoop = nil;
[oldRunLoop release];
}
- (void)start
{
if (running == OF_THREAD_RUNNING)
@throw [OFThreadStillRunningException
exceptionWithClass: [self class]
thread: self];
if (running == OF_THREAD_WAITING_FOR_JOIN) {
of_thread_detach(thread);
[returnValue release];
}
[self retain];
running = OF_THREAD_RUNNING;
if (!of_thread_new(&thread, call_main, self)) {
[self release];
@throw [OFThreadStartFailedException
exceptionWithClass: [self class]
thread: self];
}
set_thread_name(self);
}
- (id)join
{
if (running == OF_THREAD_NOT_RUNNING || !of_thread_join(thread))
@throw [OFThreadJoinFailedException
exceptionWithClass: [self class]
thread: self];
running = OF_THREAD_NOT_RUNNING;
return returnValue;
}
- copy
{
return [self retain];
}
- (OFRunLoop*)runLoop
{
#ifdef OF_HAVE_ATOMIC_OPS
if (runLoop == nil) {
OFRunLoop *tmp = [[OFRunLoop alloc] init];
if (!of_atomic_cmpswap_ptr((void**)&runLoop, nil, tmp))
[tmp release];
}
#else
@synchronized (self) {
if (runLoop == nil)
runLoop = [[OFRunLoop alloc] init];
}
#endif
return [[runLoop retain] autorelease];
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (void)setName: (OFString*)name_
{
OF_SETTER(name, name_, YES, 1)
if (running == OF_THREAD_RUNNING)
set_thread_name(self);
}
- (void)dealloc
{
if (running == OF_THREAD_RUNNING)
@throw [OFThreadStillRunningException
exceptionWithClass: [self class]
thread: self];
/*
* We should not be running anymore, but call detach in order to free
* the resources.
*/
if (running == OF_THREAD_WAITING_FOR_JOIN)
of_thread_detach(thread);
[returnValue release];
[runLoop release];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
|
}
+ (void)terminateWithObject: (id)object
{
OFThread *thread = of_tlskey_get(threadSelfKey);
if (thread != nil) {
thread->_returnValue = [object retain];
[thread handleTermination];
thread->_running = OF_THREAD_WAITING_FOR_JOIN;
}
[OFTLSKey OF_callAllDestructors];
#ifdef OF_OBJFW_RUNTIME
/*
* As the values returned by objc_autoreleasePoolPush() in the ObjFW
* runtime are not actually pointers, but sequential numbers, 0 means
* we pop everything.
*/
objc_autoreleasePoolPop(0);
#endif
[thread release];
of_thread_exit();
}
+ (void)OF_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->_thread = of_thread_current();
if (!of_tlskey_set(threadSelfKey, mainThread))
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_block_t)block
{
self = [super init];
@try {
_block = [block copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (id)main
{
[[OFRunLoop currentRunLoop] run];
return nil;
}
- (void)handleTermination
{
OFRunLoop *oldRunLoop = _runLoop;
_runLoop = nil;
[oldRunLoop release];
}
- (void)start
{
if (_running == OF_THREAD_RUNNING)
@throw [OFThreadStillRunningException
exceptionWithClass: [self class]
thread: self];
if (_running == OF_THREAD_WAITING_FOR_JOIN) {
of_thread_detach(_thread);
[_returnValue release];
}
[self retain];
_running = OF_THREAD_RUNNING;
if (!of_thread_new(&_thread, call_main, self)) {
[self release];
@throw [OFThreadStartFailedException
exceptionWithClass: [self class]
thread: self];
}
set_thread_name(self);
}
- (id)join
{
if (_running == OF_THREAD_NOT_RUNNING || !of_thread_join(_thread))
@throw [OFThreadJoinFailedException
exceptionWithClass: [self class]
thread: self];
_running = OF_THREAD_NOT_RUNNING;
return _returnValue;
}
- copy
{
return [self retain];
}
- (OFRunLoop*)runLoop
{
#ifdef OF_HAVE_ATOMIC_OPS
if (_runLoop == nil) {
OFRunLoop *tmp = [[OFRunLoop alloc] init];
if (!of_atomic_cmpswap_ptr((void**)&_runLoop, nil, tmp))
[tmp release];
}
#else
@synchronized (self) {
if (_runLoop == nil)
_runLoop = [[OFRunLoop alloc] init];
}
#endif
return [[_runLoop retain] autorelease];
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (void)setName: (OFString*)name
{
OF_SETTER(_name, name, YES, 1)
if (_running == OF_THREAD_RUNNING)
set_thread_name(self);
}
- (void)dealloc
{
if (_running == OF_THREAD_RUNNING)
@throw [OFThreadStillRunningException
exceptionWithClass: [self class]
thread: self];
/*
* We should not be running anymore, but call detach in order to free
* the resources.
*/
if (_running == OF_THREAD_WAITING_FOR_JOIN)
of_thread_detach(_thread);
[_returnValue release];
[_runLoop release];
[super dealloc];
}
@end
|
Modified src/OFThreadPool.h
from [646e84b6f4]
to [0db8d807f8].
︙ | | | ︙ | |
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
* @brief A class providing a pool of reusable threads.
*
* @note When the thread pool is released, all threads will terminate after
* they finish the job they are currently processing.
*/
@interface OFThreadPool: OFObject
{
size_t size;
OFMutableArray *threads;
volatile int count;
@public
OFList *queue;
OFCondition *queueCondition;
volatile int doneCount;
OFCondition *countCondition;
}
/*!
* @brief Returns a new thread pool with one thread for each core in the system.
*
* @warning If for some reason the number of cores in the system could not be
* determined, the pool will only have one thread!
|
|
|
|
|
|
|
|
|
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
* @brief A class providing a pool of reusable threads.
*
* @note When the thread pool is released, all threads will terminate after
* they finish the job they are currently processing.
*/
@interface OFThreadPool: OFObject
{
size_t _size;
OFMutableArray *_threads;
volatile int _count;
@public
OFList *_queue;
OFCondition *_queueCondition;
volatile int _doneCount;
OFCondition *_countCondition;
}
/*!
* @brief Returns a new thread pool with one thread for each core in the system.
*
* @warning If for some reason the number of cores in the system could not be
* determined, the pool will only have one thread!
|
︙ | | | ︙ | |
Modified src/OFThreadPool.m
from [b48920db5d]
to [75625ed3ab].
︙ | | | ︙ | |
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#import "OFCondition.h"
#import "OFSystemInfo.h"
#import "autorelease.h"
@interface OFThreadPoolJob: OFObject
{
id target;
SEL selector;
id object;
#ifdef OF_HAVE_BLOCKS
of_thread_pool_block_t block;
#endif
}
+ (instancetype)jobWithTarget: (id)target
selector: (SEL)selector
object: (id)object;
#ifdef OF_HAVE_BLOCKS
|
|
|
|
|
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#import "OFCondition.h"
#import "OFSystemInfo.h"
#import "autorelease.h"
@interface OFThreadPoolJob: OFObject
{
id _target;
SEL _selector;
id _object;
#ifdef OF_HAVE_BLOCKS
of_thread_pool_block_t _block;
#endif
}
+ (instancetype)jobWithTarget: (id)target
selector: (SEL)selector
object: (id)object;
#ifdef OF_HAVE_BLOCKS
|
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
+ (instancetype)jobWithBlock: (of_thread_pool_block_t)block
{
return [[(OFThreadPoolJob*)[self alloc]
initWithBlock: block] autorelease];
}
#endif
- initWithTarget: (id)target_
selector: (SEL)selector_
object: (id)object_
{
self = [super init];
@try {
target = [target_ retain];
selector = selector_;
object = [object_ retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_pool_block_t)block_
{
self = [super init];
@try {
block = [block_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[target release];
[object release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
[super dealloc];
}
- (void)perform
{
#ifdef OF_HAVE_BLOCKS
if (block != NULL)
block();
else
#endif
[object performSelector: selector
withObject: object];
}
@end
@interface OFThreadPoolThread: OFThread
{
OFList *queue;
OFCondition *queueCondition, *countCondition;
@public
volatile BOOL terminate;
volatile int *doneCount;
}
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool;
- initWithThreadPool: (OFThreadPool*)threadPool;
@end
@implementation OFThreadPoolThread
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool
{
return [[[self alloc] initWithThreadPool: threadPool] autorelease];
}
- initWithThreadPool: (OFThreadPool*)threadPool
{
self = [super init];
@try {
queue = [threadPool->queue retain];
queueCondition = [threadPool->queueCondition retain];
countCondition = [threadPool->countCondition retain];
doneCount = &threadPool->doneCount;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[queue release];
[queueCondition release];
[countCondition release];
[super dealloc];
}
- (id)main
{
void *pool;
if (terminate)
return nil;
pool = objc_autoreleasePoolPush();
for (;;) {
OFThreadPoolJob *job;
[queueCondition lock];
@try {
of_list_object_t *listObject;
if (terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
listObject = [queue firstListObject];
while (listObject == NULL) {
[queueCondition wait];
if (terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
listObject = [queue firstListObject];
}
job = [[listObject->object retain] autorelease];
[queue removeListObject: listObject];
} @finally {
[queueCondition unlock];
}
if (terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
[job perform];
if (terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
objc_autoreleasePoolPop(pool);
pool = objc_autoreleasePoolPush();
[countCondition lock];
@try {
if (terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
(*doneCount)++;
[countCondition signal];
} @finally {
[countCondition unlock];
}
}
}
@end
@implementation OFThreadPool
+ (instancetype)threadPool
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
+ (instancetype)jobWithBlock: (of_thread_pool_block_t)block
{
return [[(OFThreadPoolJob*)[self alloc]
initWithBlock: block] autorelease];
}
#endif
- initWithTarget: (id)target
selector: (SEL)selector
object: (id)object
{
self = [super init];
@try {
_target = [target retain];
_selector = selector;
_object = [object retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#ifdef OF_HAVE_BLOCKS
- initWithBlock: (of_thread_pool_block_t)block
{
self = [super init];
@try {
_block = [block copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
[_target release];
[_object release];
#ifdef OF_HAVE_BLOCKS
[_block release];
#endif
[super dealloc];
}
- (void)perform
{
#ifdef OF_HAVE_BLOCKS
if (_block != NULL)
_block();
else
#endif
[_target performSelector: _selector
withObject: _object];
}
@end
@interface OFThreadPoolThread: OFThread
{
OFList *_queue;
OFCondition *_queueCondition, *_countCondition;
@public
volatile BOOL _terminate;
volatile int *_doneCount;
}
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool;
- initWithThreadPool: (OFThreadPool*)threadPool;
@end
@implementation OFThreadPoolThread
+ (instancetype)threadWithThreadPool: (OFThreadPool*)threadPool
{
return [[[self alloc] initWithThreadPool: threadPool] autorelease];
}
- initWithThreadPool: (OFThreadPool*)threadPool
{
self = [super init];
@try {
_queue = [threadPool->_queue retain];
_queueCondition = [threadPool->_queueCondition retain];
_countCondition = [threadPool->_countCondition retain];
_doneCount = &threadPool->_doneCount;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_queue release];
[_queueCondition release];
[_countCondition release];
[super dealloc];
}
- (id)main
{
void *pool;
if (_terminate)
return nil;
pool = objc_autoreleasePoolPush();
for (;;) {
OFThreadPoolJob *job;
[_queueCondition lock];
@try {
of_list_object_t *listObject;
if (_terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
listObject = [_queue firstListObject];
while (listObject == NULL) {
[_queueCondition wait];
if (_terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
listObject = [_queue firstListObject];
}
job = [[listObject->object retain] autorelease];
[_queue removeListObject: listObject];
} @finally {
[_queueCondition unlock];
}
if (_terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
[job perform];
if (_terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
objc_autoreleasePoolPop(pool);
pool = objc_autoreleasePoolPush();
[_countCondition lock];
@try {
if (_terminate) {
objc_autoreleasePoolPop(pool);
return nil;
}
(*_doneCount)++;
[_countCondition signal];
} @finally {
[_countCondition unlock];
}
}
}
@end
@implementation OFThreadPool
+ (instancetype)threadPool
|
︙ | | | ︙ | |
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
|
}
- init
{
return [self initWithSize: [OFSystemInfo numberOfCPUs]];
}
- initWithSize: (size_t)size_
{
self = [super init];
@try {
size_t i;
size = size_;
threads = [[OFMutableArray alloc] init];
queue = [[OFList alloc] init];
queueCondition = [[OFCondition alloc] init];
countCondition = [[OFCondition alloc] init];
for (i = 0; i < size; i++) {
void *pool = objc_autoreleasePoolPush();
OFThreadPoolThread *thread =
[OFThreadPoolThread threadWithThreadPool: self];
[threads addObject: thread];
objc_autoreleasePoolPop(pool);
}
/*
* We need to start the threads in a separate loop to make sure
* threads is not modified anymore to prevent a race condition.
*/
for (i = 0; i < size; i++) {
OFThreadPoolThread *thread = [threads objectAtIndex: i];
[thread start];
}
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
void *pool = objc_autoreleasePoolPush();
[queueCondition lock];
@try {
[countCondition lock];
@try {
OFEnumerator *enumerator = [threads objectEnumerator];
OFThreadPoolThread *thread;
while ((thread = [enumerator nextObject]) != nil)
thread->terminate = YES;
} @finally {
[countCondition unlock];
}
[queueCondition broadcast];
} @finally {
[queueCondition unlock];
}
objc_autoreleasePoolPop(pool);
[threads release];
[queue release];
[queueCondition release];
[countCondition release];
[super dealloc];
}
- (void)OF_dispatchJob: (OFThreadPoolJob*)job
{
[countCondition lock];
count++;
[countCondition unlock];
[queueCondition lock];
@try {
[queue appendObject: job];
[queueCondition signal];
} @finally {
[queueCondition unlock];
}
}
- (void)waitUntilDone
{
for (;;) {
[countCondition lock];
@try {
if (doneCount == count)
return;
[countCondition wait];
} @finally {
[countCondition unlock];
}
}
}
- (void)dispatchWithTarget: (id)target
selector: (SEL)selector
object: (id)object
|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
}
- init
{
return [self initWithSize: [OFSystemInfo numberOfCPUs]];
}
- initWithSize: (size_t)size
{
self = [super init];
@try {
size_t i;
_size = size;
_threads = [[OFMutableArray alloc] init];
_queue = [[OFList alloc] init];
_queueCondition = [[OFCondition alloc] init];
_countCondition = [[OFCondition alloc] init];
for (i = 0; i < size; i++) {
void *pool = objc_autoreleasePoolPush();
OFThreadPoolThread *thread =
[OFThreadPoolThread threadWithThreadPool: self];
[_threads addObject: thread];
objc_autoreleasePoolPop(pool);
}
/*
* We need to start the threads in a separate loop to make sure
* threads is not modified anymore to prevent a race condition.
*/
for (i = 0; i < size; i++)
[[_threads objectAtIndex: i] start];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
void *pool = objc_autoreleasePoolPush();
[_queueCondition lock];
@try {
[_countCondition lock];
@try {
OFEnumerator *enumerator = [_threads objectEnumerator];
OFThreadPoolThread *thread;
while ((thread = [enumerator nextObject]) != nil)
thread->_terminate = YES;
} @finally {
[_countCondition unlock];
}
[_queueCondition broadcast];
} @finally {
[_queueCondition unlock];
}
objc_autoreleasePoolPop(pool);
[_threads release];
[_queue release];
[_queueCondition release];
[_countCondition release];
[super dealloc];
}
- (void)OF_dispatchJob: (OFThreadPoolJob*)job
{
[_countCondition lock];
_count++;
[_countCondition unlock];
[_queueCondition lock];
@try {
[_queue appendObject: job];
[_queueCondition signal];
} @finally {
[_queueCondition unlock];
}
}
- (void)waitUntilDone
{
for (;;) {
[_countCondition lock];
@try {
if (_doneCount == _count)
return;
[_countCondition wait];
} @finally {
[_countCondition unlock];
}
}
}
- (void)dispatchWithTarget: (id)target
selector: (SEL)selector
object: (id)object
|
︙ | | | ︙ | |
373
374
375
376
377
378
379
380
381
382
|
{
[self OF_dispatchJob: [OFThreadPoolJob jobWithBlock: block]];
}
#endif
- (size_t)size
{
return size;
}
@end
|
|
|
370
371
372
373
374
375
376
377
378
379
|
{
[self OF_dispatchJob: [OFThreadPoolJob jobWithBlock: block]];
}
#endif
- (size_t)size
{
return _size;
}
@end
|
Modified src/OFTimer.h
from [b48acf13c1]
to [06b74b5159].
︙ | | | ︙ | |
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
|
#endif
/*!
* @brief A class for creating and firing timers.
*/
@interface OFTimer: OFObject <OFComparing>
{
OFDate *fireDate;
double interval;
id target, object1, object2;
SEL selector;
uint8_t arguments;
BOOL repeats;
#ifdef OF_HAVE_BLOCKS
of_timer_block_t block;
#endif
BOOL isValid;
#ifdef OF_HAVE_THREADS
OFCondition *condition;
BOOL done;
#endif
OFRunLoop *inRunLoop;
}
#ifdef OF_HAVE_PROPERTIES
@property (retain) OFDate *fireDate;
#endif
/*!
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#endif
/*!
* @brief A class for creating and firing timers.
*/
@interface OFTimer: OFObject <OFComparing>
{
OFDate *_fireDate;
double _interval;
id _target, _object1, _object2;
SEL _selector;
uint8_t _arguments;
BOOL _repeats;
#ifdef OF_HAVE_BLOCKS
of_timer_block_t _block;
#endif
BOOL _valid;
#ifdef OF_HAVE_THREADS
OFCondition *_condition;
BOOL _done;
#endif
OFRunLoop *_inRunLoop;
}
#ifdef OF_HAVE_PROPERTIES
@property (retain) OFDate *fireDate;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/OFTimer.m
from [937b3c80f0]
to [f650b3c206].
︙ | | | ︙ | |
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
|
[self release];
@throw e;
}
abort();
}
- OF_initWithFireDate: (OFDate*)fireDate_
interval: (double)interval_
target: (id)target_
selector: (SEL)selector_
object: (id)object1_
object: (id)object2_
arguments: (uint8_t)arguments_
repeats: (BOOL)repeats_
{
self = [super init];
@try {
fireDate = [fireDate_ retain];
interval = interval_;
target = [target_ retain];
selector = selector_;
object1 = [object1_ retain];
object2 = [object2_ retain];
arguments = arguments_;
repeats = repeats_;
isValid = YES;
#ifdef OF_HAVE_THREADS
condition = [[OFCondition alloc] init];
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithFireDate: (OFDate*)fireDate_
interval: (double)interval_
target: (id)target_
selector: (SEL)selector_
repeats: (BOOL)repeats_
{
return [self OF_initWithFireDate: fireDate_
interval: interval_
target: target_
selector: selector_
object: nil
object: nil
arguments: 0
repeats: repeats_];
}
- initWithFireDate: (OFDate*)fireDate_
interval: (double)interval_
target: (id)target_
selector: (SEL)selector_
object: (id)object
repeats: (BOOL)repeats_
{
return [self OF_initWithFireDate: fireDate_
interval: interval_
target: target_
selector: selector_
object: object
object: nil
arguments: 1
repeats: repeats_];
}
- initWithFireDate: (OFDate*)fireDate_
interval: (double)interval_
target: (id)target_
selector: (SEL)selector_
object: (id)object1_
object: (id)object2_
repeats: (BOOL)repeats_
{
return [self OF_initWithFireDate: fireDate_
interval: interval_
target: target_
selector: selector_
object: object1_
object: object2_
arguments: 2
repeats: repeats_];
}
#ifdef OF_HAVE_BLOCKS
- initWithFireDate: (OFDate*)fireDate_
interval: (double)interval_
repeats: (BOOL)repeats_
block: (of_timer_block_t)block_
{
self = [super init];
@try {
fireDate = [fireDate_ retain];
interval = interval_;
repeats = repeats_;
block = [block_ copy];
isValid = YES;
# ifdef OF_HAVE_THREADS
condition = [[OFCondition alloc] init];
# endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
/*
* The run loop references the timer, so it should never be deallocated
* if it is still in a run loop.
*/
assert(inRunLoop == nil);
[fireDate release];
[target release];
[object1 release];
[object2 release];
#ifdef OF_HAVE_BLOCKS
[block release];
#endif
#ifdef OF_HAVE_THREADS
[condition release];
#endif
[super dealloc];
}
- (of_comparison_result_t)compare: (id <OFComparing>)object_
{
OFTimer *otherTimer;
if (![object_ isKindOfClass: [OFTimer class]])
@throw[OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
otherTimer = (OFTimer*)object_;
return [fireDate compare: otherTimer->fireDate];
}
- (void)fire
{
OF_ENSURE(arguments <= 2);
#ifdef OF_HAVE_BLOCKS
if (block != NULL)
block(self);
else {
#endif
switch (arguments) {
case 0:
[target performSelector: selector];
break;
case 1:
[target performSelector: selector
withObject: object1];
break;
case 2:
[target performSelector: selector
withObject: object1
withObject: object2];
break;
}
#ifdef OF_HAVE_BLOCKS
}
#endif
#ifdef OF_HAVE_THREADS
[condition lock];
@try {
done = YES;
[condition signal];
} @finally {
[condition unlock];
}
#endif
if (repeats && isValid) {
OFDate *old = fireDate;
fireDate = [[OFDate alloc]
initWithTimeIntervalSinceNow: interval];
[old release];
[[OFRunLoop currentRunLoop] addTimer: self];
} else
[self invalidate];
}
- (OFDate*)fireDate
{
OF_GETTER(fireDate, YES)
}
- (void)setFireDate: (OFDate*)fireDate_
{
[self retain];
@try {
@synchronized (self) {
[inRunLoop OF_removeTimer: self];
OF_SETTER(fireDate, fireDate_, YES, 0)
[inRunLoop addTimer: self];
}
} @finally {
[self release];
}
}
- (double)timeInterval
{
return interval;
}
- (void)invalidate
{
isValid = NO;
[target release];
target = nil;
}
- (BOOL)isValid
{
return isValid;
}
#ifdef OF_HAVE_THREADS
- (void)waitUntilDone
{
[condition lock];
@try {
if (done) {
done = NO;
return;
}
[condition wait];
} @finally {
[condition unlock];
}
}
#endif
- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop_
{
OF_SETTER(inRunLoop, inRunLoop_, YES, 0)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
|
[self release];
@throw e;
}
abort();
}
- OF_initWithFireDate: (OFDate*)fireDate
interval: (double)interval
target: (id)target
selector: (SEL)selector
object: (id)object1
object: (id)object2
arguments: (uint8_t)arguments
repeats: (BOOL)repeats
{
self = [super init];
@try {
_fireDate = [fireDate retain];
_interval = interval;
_target = [target retain];
_selector = selector;
_object1 = [object1 retain];
_object2 = [object2 retain];
_arguments = arguments;
_repeats = repeats;
_valid = YES;
#ifdef OF_HAVE_THREADS
_condition = [[OFCondition alloc] init];
#endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithFireDate: (OFDate*)fireDate
interval: (double)interval
target: (id)target
selector: (SEL)selector
repeats: (BOOL)repeats
{
return [self OF_initWithFireDate: fireDate
interval: interval
target: target
selector: selector
object: nil
object: nil
arguments: 0
repeats: repeats];
}
- initWithFireDate: (OFDate*)fireDate
interval: (double)interval
target: (id)target
selector: (SEL)selector
object: (id)object
repeats: (BOOL)repeats
{
return [self OF_initWithFireDate: fireDate
interval: interval
target: target
selector: selector
object: object
object: nil
arguments: 1
repeats: repeats];
}
- initWithFireDate: (OFDate*)fireDate
interval: (double)interval
target: (id)target
selector: (SEL)selector
object: (id)object1
object: (id)object2
repeats: (BOOL)repeats
{
return [self OF_initWithFireDate: fireDate
interval: interval
target: target
selector: selector
object: object1
object: object2
arguments: 2
repeats: repeats];
}
#ifdef OF_HAVE_BLOCKS
- initWithFireDate: (OFDate*)fireDate
interval: (double)interval
repeats: (BOOL)repeats
block: (of_timer_block_t)block
{
self = [super init];
@try {
_fireDate = [fireDate retain];
_interval = interval;
_repeats = repeats;
_block = [block copy];
_valid = YES;
# ifdef OF_HAVE_THREADS
_condition = [[OFCondition alloc] init];
# endif
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
#endif
- (void)dealloc
{
/*
* The run loop references the timer, so it should never be deallocated
* if it is still in a run loop.
*/
assert(_inRunLoop == nil);
[_fireDate release];
[_target release];
[_object1 release];
[_object2 release];
#ifdef OF_HAVE_BLOCKS
[_block release];
#endif
#ifdef OF_HAVE_THREADS
[_condition release];
#endif
[super dealloc];
}
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
OFTimer *timer;
if (![object isKindOfClass: [OFTimer class]])
@throw[OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
timer = (OFTimer*)object;
return [_fireDate compare: timer->_fireDate];
}
- (void)fire
{
OF_ENSURE(_arguments <= 2);
#ifdef OF_HAVE_BLOCKS
if (_block != NULL)
_block(self);
else {
#endif
switch (_arguments) {
case 0:
[_target performSelector: _selector];
break;
case 1:
[_target performSelector: _selector
withObject: _object1];
break;
case 2:
[_target performSelector: _selector
withObject: _object1
withObject: _object2];
break;
}
#ifdef OF_HAVE_BLOCKS
}
#endif
#ifdef OF_HAVE_THREADS
[_condition lock];
@try {
_done = YES;
[_condition signal];
} @finally {
[_condition unlock];
}
#endif
if (_repeats && _valid) {
OFDate *old = _fireDate;
_fireDate = [[OFDate alloc]
initWithTimeIntervalSinceNow: _interval];
[old release];
[[OFRunLoop currentRunLoop] addTimer: self];
} else
[self invalidate];
}
- (OFDate*)fireDate
{
OF_GETTER(_fireDate, YES)
}
- (void)setFireDate: (OFDate*)fireDate
{
[self retain];
@try {
@synchronized (self) {
[_inRunLoop OF_removeTimer: self];
OF_SETTER(_fireDate, fireDate, YES, 0)
[_inRunLoop addTimer: self];
}
} @finally {
[self release];
}
}
- (double)timeInterval
{
return _interval;
}
- (void)invalidate
{
_valid = NO;
[_target release];
_target = nil;
}
- (BOOL)isValid
{
return _valid;
}
#ifdef OF_HAVE_THREADS
- (void)waitUntilDone
{
[_condition lock];
@try {
if (_done) {
_done = NO;
return;
}
[_condition wait];
} @finally {
[_condition unlock];
}
}
#endif
- (void)OF_setInRunLoop: (OFRunLoop*)inRunLoop
{
OF_SETTER(_inRunLoop, inRunLoop, YES, 0)
}
@end
|
Modified src/OFURL.h
from [74eb4f4df2]
to [17bbc676ef].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
@class OFString;
/*!
* @brief A class for parsing URLs and accessing parts of it.
*/
@interface OFURL: OFObject <OFCopying, OFSerialization>
{
OFString *scheme;
OFString *host;
uint16_t port;
OFString *user;
OFString *password;
OFString *path;
OFString *parameters;
OFString *query;
OFString *fragment;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *scheme;
@property (copy) OFString *host;
@property uint16_t port;
@property (copy) OFString *user;
|
<
|
|
|
<
<
<
<
<
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFString;
/*!
* @brief A class for parsing URLs and accessing parts of it.
*/
@interface OFURL: OFObject <OFCopying, OFSerialization>
{
OFString *_scheme, *_host;
uint16_t _port;
OFString *_user, *_password, *_path, *_parameters, *_query, *_fragment;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *scheme;
@property (copy) OFString *host;
@property uint16_t port;
@property (copy) OFString *user;
|
︙ | | | ︙ | |
Modified src/OFURL.m
from [2267fdd898]
to [fcf898c186].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: [string UTF8StringLength]];
UTF8String = UTF8String2;
if (!strncmp(UTF8String, "file://", 7)) {
scheme = @"file";
path = [[OFString alloc]
initWithUTF8String: UTF8String + 7];
return self;
} else if (!strncmp(UTF8String, "http://", 7)) {
scheme = @"http";
UTF8String += 7;
} else if (!strncmp(UTF8String, "https://", 8)) {
scheme = @"https";
UTF8String += 8;
} else
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
if ((tmp = strchr(UTF8String, '/')) != NULL) {
*tmp = '\0';
tmp++;
}
if ((tmp2 = strchr(UTF8String, '@')) != NULL) {
char *tmp3;
*tmp2 = '\0';
tmp2++;
if ((tmp3 = strchr(UTF8String, ':')) != NULL) {
*tmp3 = '\0';
tmp3++;
user = [[OFString alloc]
initWithUTF8String: UTF8String];
password = [[OFString alloc]
initWithUTF8String: tmp3];
} else
user = [[OFString alloc]
initWithUTF8String: UTF8String];
UTF8String = tmp2;
}
if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
void *pool;
OFString *portString;
*tmp2 = '\0';
tmp2++;
host = [[OFString alloc]
initWithUTF8String: UTF8String];
pool = objc_autoreleasePoolPush();
portString = [OFString stringWithUTF8String: tmp2];
if ([portString decimalValue] > 65535)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
port = [portString decimalValue];
if (port == 0)
port = 80;
objc_autoreleasePoolPop(pool);
} else {
host = [[OFString alloc]
initWithUTF8String: UTF8String];
if ([scheme isEqual: @"http"])
port = 80;
else if ([scheme isEqual: @"https"])
port = 443;
else
assert(0);
}
if ((UTF8String = tmp) != NULL) {
if ((tmp = strchr(UTF8String, '#')) != NULL) {
*tmp = '\0';
fragment = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, '?')) != NULL) {
*tmp = '\0';
query = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, ';')) != NULL) {
*tmp = '\0';
parameters = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
path = [[OFString alloc] initWithFormat: @"/%s",
UTF8String];
} else
path = @"";
} @catch (id e) {
[self release];
@throw e;
} @finally {
free(UTF8String2);
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: [string UTF8StringLength]];
UTF8String = UTF8String2;
if (!strncmp(UTF8String, "file://", 7)) {
_scheme = @"file";
_path = [[OFString alloc]
initWithUTF8String: UTF8String + 7];
return self;
} else if (!strncmp(UTF8String, "http://", 7)) {
_scheme = @"http";
UTF8String += 7;
} else if (!strncmp(UTF8String, "https://", 8)) {
_scheme = @"https";
UTF8String += 8;
} else
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
if ((tmp = strchr(UTF8String, '/')) != NULL) {
*tmp = '\0';
tmp++;
}
if ((tmp2 = strchr(UTF8String, '@')) != NULL) {
char *tmp3;
*tmp2 = '\0';
tmp2++;
if ((tmp3 = strchr(UTF8String, ':')) != NULL) {
*tmp3 = '\0';
tmp3++;
_user = [[OFString alloc]
initWithUTF8String: UTF8String];
_password = [[OFString alloc]
initWithUTF8String: tmp3];
} else
_user = [[OFString alloc]
initWithUTF8String: UTF8String];
UTF8String = tmp2;
}
if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
void *pool;
OFString *portString;
*tmp2 = '\0';
tmp2++;
_host = [[OFString alloc]
initWithUTF8String: UTF8String];
pool = objc_autoreleasePoolPush();
portString = [OFString stringWithUTF8String: tmp2];
if ([portString decimalValue] > 65535)
@throw [OFInvalidFormatException
exceptionWithClass: [self class]];
_port = [portString decimalValue];
if (_port == 0)
_port = 80;
objc_autoreleasePoolPop(pool);
} else {
_host = [[OFString alloc]
initWithUTF8String: UTF8String];
if ([_scheme isEqual: @"http"])
_port = 80;
else if ([_scheme isEqual: @"https"])
_port = 443;
else
assert(0);
}
if ((UTF8String = tmp) != NULL) {
if ((tmp = strchr(UTF8String, '#')) != NULL) {
*tmp = '\0';
_fragment = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, '?')) != NULL) {
*tmp = '\0';
_query = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, ';')) != NULL) {
*tmp = '\0';
_parameters = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
_path = [[OFString alloc] initWithFormat: @"/%s",
UTF8String];
} else
_path = @"";
} @catch (id e) {
[self release];
@throw e;
} @finally {
free(UTF8String2);
}
|
︙ | | | ︙ | |
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
return [self initWithString: string];
self = [super init];
@try {
char *tmp;
scheme = [URL->scheme copy];
host = [URL->host copy];
port = URL->port;
user = [URL->user copy];
password = [URL->password copy];
if ((UTF8String2 = strdup([string UTF8String])) == NULL)
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: [string UTF8StringLength]];
UTF8String = UTF8String2;
if ((tmp = strchr(UTF8String, '#')) != NULL) {
*tmp = '\0';
fragment = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, '?')) != NULL) {
*tmp = '\0';
query = [[OFString alloc] initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, ';')) != NULL) {
*tmp = '\0';
parameters = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if (*UTF8String == '/')
path = [[OFString alloc]
initWithUTF8String: UTF8String];
else {
void *pool;
OFString *s;
pool = objc_autoreleasePoolPush();
if ([URL->path hasSuffix: @"/"])
s = [OFString stringWithFormat: @"%@%s",
URL->path,
UTF8String];
else
s = [OFString stringWithFormat: @"%@/../%s",
URL->path,
UTF8String];
path = [[s stringByStandardizingURLPath] copy];
objc_autoreleasePoolPop(pool);
}
} @catch (id e) {
[self release];
@throw e;
} @finally {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
return [self initWithString: string];
self = [super init];
@try {
char *tmp;
_scheme = [URL->_scheme copy];
_host = [URL->_host copy];
_port = URL->_port;
_user = [URL->_user copy];
_password = [URL->_password copy];
if ((UTF8String2 = strdup([string UTF8String])) == NULL)
@throw [OFOutOfMemoryException
exceptionWithClass: [self class]
requestedSize: [string UTF8StringLength]];
UTF8String = UTF8String2;
if ((tmp = strchr(UTF8String, '#')) != NULL) {
*tmp = '\0';
_fragment = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, '?')) != NULL) {
*tmp = '\0';
_query = [[OFString alloc] initWithUTF8String: tmp + 1];
}
if ((tmp = strchr(UTF8String, ';')) != NULL) {
*tmp = '\0';
_parameters = [[OFString alloc]
initWithUTF8String: tmp + 1];
}
if (*UTF8String == '/')
_path = [[OFString alloc]
initWithUTF8String: UTF8String];
else {
void *pool;
OFString *s;
pool = objc_autoreleasePoolPush();
if ([URL->_path hasSuffix: @"/"])
s = [OFString stringWithFormat: @"%@%s",
URL->_path,
UTF8String];
else
s = [OFString stringWithFormat: @"%@/../%s",
URL->_path,
UTF8String];
_path = [[s stringByStandardizingURLPath] copy];
objc_autoreleasePoolPop(pool);
}
} @catch (id e) {
[self release];
@throw e;
} @finally {
|
︙ | | | ︙ | |
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
|
}
return self;
}
- (void)dealloc
{
[scheme release];
[host release];
[user release];
[password release];
[path release];
[parameters release];
[query release];
[fragment release];
[super dealloc];
}
- (BOOL)isEqual: (id)object
{
OFURL *otherURL;
if (![object isKindOfClass: [OFURL class]])
return NO;
otherURL = object;
if (![otherURL->scheme isEqual: scheme])
return NO;
if (![otherURL->host isEqual: host])
return NO;
if (otherURL->port != port)
return NO;
if (otherURL->user != user && ![otherURL->user isEqual: user])
return NO;
if (otherURL->password != password &&
![otherURL->password isEqual: password])
return NO;
if (![otherURL->path isEqual: path])
return NO;
if (otherURL->parameters != parameters &&
![otherURL->parameters isEqual: parameters])
return NO;
if (otherURL->query != query &&
![otherURL->query isEqual: query])
return NO;
if (otherURL->fragment != fragment &&
![otherURL->fragment isEqual: fragment])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [scheme hash]);
OF_HASH_ADD_HASH(hash, [host hash]);
OF_HASH_ADD(hash, (port & 0xFF00) >> 8);
OF_HASH_ADD(hash, port & 0xFF);
OF_HASH_ADD_HASH(hash, [user hash]);
OF_HASH_ADD_HASH(hash, [password hash]);
OF_HASH_ADD_HASH(hash, [path hash]);
OF_HASH_ADD_HASH(hash, [parameters hash]);
OF_HASH_ADD_HASH(hash, [query hash]);
OF_HASH_ADD_HASH(hash, [fragment hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- copy
{
OFURL *copy = [[[self class] alloc] init];
@try {
copy->scheme = [scheme copy];
copy->host = [host copy];
copy->port = port;
copy->user = [user copy];
copy->password = [password copy];
copy->path = [path copy];
copy->parameters = [parameters copy];
copy->query = [query copy];
copy->fragment = [fragment copy];
} @catch (id e) {
[copy release];
@throw e;
}
return copy;
}
- (OFString*)scheme
{
OF_GETTER(scheme, YES)
}
- (void)setScheme: (OFString*)scheme_
{
if (![scheme_ isEqual: @"http"] && ![scheme_ isEqual: @"https"])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(scheme, scheme_, YES, 1)
}
- (OFString*)host
{
OF_GETTER(host, YES)
}
- (void)setHost: (OFString*)host_
{
OF_SETTER(host, host_, YES, 1)
}
- (uint16_t)port
{
return port;
}
- (void)setPort: (uint16_t)port_
{
port = port_;
}
- (OFString*)user
{
OF_GETTER(user, YES)
}
- (void)setUser: (OFString*)user_
{
OF_SETTER(user, user_, YES, 1)
}
- (OFString*)password
{
OF_GETTER(password, YES)
}
- (void)setPassword: (OFString*)password_
{
OF_SETTER(password, password_, YES, 1)
}
- (OFString*)path
{
OF_GETTER(path, YES)
}
- (void)setPath: (OFString*)path_
{
if (([scheme isEqual: @"http"] || [scheme isEqual: @"https"]) &&
![path_ hasPrefix: @"/"])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(path, path_, YES, 1)
}
- (OFString*)parameters
{
OF_GETTER(parameters, YES)
}
- (void)setParameters: (OFString*)parameters_
{
OF_SETTER(parameters, parameters_, YES, 1)
}
- (OFString*)query
{
OF_GETTER(query, YES)
}
- (void)setQuery: (OFString*)query_
{
OF_SETTER(query, query_, YES, 1)
}
- (OFString*)fragment
{
OF_GETTER(fragment, YES)
}
- (void)setFragment: (OFString*)fragment_
{
OF_SETTER(fragment, fragment_, YES, 1)
}
- (OFString*)string
{
OFMutableString *ret = [OFMutableString stringWithFormat: @"%@://",
scheme];
BOOL needPort = YES;
if ([scheme isEqual: @"file"]) {
if (path != nil)
[ret appendString: path];
return ret;
}
if (user != nil && password != nil)
[ret appendFormat: @"%@:%@@", user, password];
else if (user != nil)
[ret appendFormat: @"%@@", user];
if (host != nil)
[ret appendString: host];
if (([scheme isEqual: @"http"] && port == 80) ||
([scheme isEqual: @"https"] && port == 443))
needPort = NO;
if (needPort)
[ret appendFormat: @":%d", port];
if (path != nil)
[ret appendString: path];
if (parameters != nil)
[ret appendFormat: @";%@", parameters];
if (query != nil)
[ret appendFormat: @"?%@", query];
if (fragment != nil)
[ret appendFormat: @"#%@", fragment];
[ret makeImmutable];
return ret;
}
- (OFString*)description
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
|
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
|
}
return self;
}
- (void)dealloc
{
[_scheme release];
[_host release];
[_user release];
[_password release];
[_path release];
[_parameters release];
[_query release];
[_fragment release];
[super dealloc];
}
- (BOOL)isEqual: (id)object
{
OFURL *URL;
if (![object isKindOfClass: [OFURL class]])
return NO;
URL = object;
if (![URL->_scheme isEqual: _scheme])
return NO;
if (![URL->_host isEqual: _host])
return NO;
if (URL->_port != _port)
return NO;
if (URL->_user != _user && ![URL->_user isEqual: _user])
return NO;
if (URL->_password != _password &&
![URL->_password isEqual: _password])
return NO;
if (![URL->_path isEqual: _path])
return NO;
if (URL->_parameters != _parameters &&
![URL->_parameters isEqual: _parameters])
return NO;
if (URL->_query != _query &&
![URL->_query isEqual: _query])
return NO;
if (URL->_fragment != _fragment &&
![URL->_fragment isEqual: _fragment])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_scheme hash]);
OF_HASH_ADD_HASH(hash, [_host hash]);
OF_HASH_ADD(hash, (_port & 0xFF00) >> 8);
OF_HASH_ADD(hash, _port & 0xFF);
OF_HASH_ADD_HASH(hash, [_user hash]);
OF_HASH_ADD_HASH(hash, [_password hash]);
OF_HASH_ADD_HASH(hash, [_path hash]);
OF_HASH_ADD_HASH(hash, [_parameters hash]);
OF_HASH_ADD_HASH(hash, [_query hash]);
OF_HASH_ADD_HASH(hash, [_fragment hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- copy
{
OFURL *copy = [[[self class] alloc] init];
@try {
copy->_scheme = [_scheme copy];
copy->_host = [_host copy];
copy->_port = _port;
copy->_user = [_user copy];
copy->_password = [_password copy];
copy->_path = [_path copy];
copy->_parameters = [_parameters copy];
copy->_query = [_query copy];
copy->_fragment = [_fragment copy];
} @catch (id e) {
[copy release];
@throw e;
}
return copy;
}
- (OFString*)scheme
{
OF_GETTER(_scheme, YES)
}
- (void)setScheme: (OFString*)scheme
{
if (![scheme isEqual: @"http"] && ![scheme isEqual: @"https"])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(_scheme, scheme, YES, 1)
}
- (OFString*)host
{
OF_GETTER(_host, YES)
}
- (void)setHost: (OFString*)host
{
OF_SETTER(_host, host, YES, 1)
}
- (uint16_t)port
{
return _port;
}
- (void)setPort: (uint16_t)port
{
_port = port;
}
- (OFString*)user
{
OF_GETTER(_user, YES)
}
- (void)setUser: (OFString*)user
{
OF_SETTER(_user, user, YES, 1)
}
- (OFString*)password
{
OF_GETTER(_password, YES)
}
- (void)setPassword: (OFString*)password
{
OF_SETTER(_password, password, YES, 1)
}
- (OFString*)path
{
OF_GETTER(_path, YES)
}
- (void)setPath: (OFString*)path
{
if (([_scheme isEqual: @"http"] || [_scheme isEqual: @"https"]) &&
![path hasPrefix: @"/"])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(_path, path, YES, 1)
}
- (OFString*)parameters
{
OF_GETTER(_parameters, YES)
}
- (void)setParameters: (OFString*)parameters
{
OF_SETTER(_parameters, parameters, YES, 1)
}
- (OFString*)query
{
OF_GETTER(_query, YES)
}
- (void)setQuery: (OFString*)query
{
OF_SETTER(_query, query, YES, 1)
}
- (OFString*)fragment
{
OF_GETTER(_fragment, YES)
}
- (void)setFragment: (OFString*)fragment
{
OF_SETTER(_fragment, fragment, YES, 1)
}
- (OFString*)string
{
OFMutableString *ret = [OFMutableString stringWithFormat: @"%@://",
_scheme];
if ([_scheme isEqual: @"file"]) {
if (_path != nil)
[ret appendString: _path];
return ret;
}
if (_user != nil && _password != nil)
[ret appendFormat: @"%@:%@@", _user, _password];
else if (_user != nil)
[ret appendFormat: @"%@@", _user];
if (_host != nil)
[ret appendString: _host];
if (([_scheme isEqual: @"http"] && _port != 80) ||
([_scheme isEqual: @"https"] && _port != 443))
[ret appendFormat: @":%u", _port];
if (_path != nil)
[ret appendString: _path];
if (_parameters != nil)
[ret appendFormat: @";%@", _parameters];
if (_query != nil)
[ret appendFormat: @"?%@", _query];
if (_fragment != nil)
[ret appendFormat: @"#%@", _fragment];
[ret makeImmutable];
return ret;
}
- (OFString*)description
|
︙ | | | ︙ | |
Modified src/OFXMLAttribute.h
from [86af9b92f4]
to [45b1e6b315].
︙ | | | ︙ | |
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
|
/*!
* @brief A representation of an attribute of an XML element as an object.
*/
@interface OFXMLAttribute: OFXMLNode
{
@public
OFString *name;
OFString *ns;
OFString *stringValue;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name;
@property (readonly, copy, getter=namespace) OFString *ns;
@property (readonly, copy) OFString *stringValue;
#endif
/*!
* @brief Creates a new XML attribute.
*
* @param name The name of the attribute
* @param stringValue The string value of the attribute
* @return A new autoreleased OFXMLAttribute with the specified parameters
*/
+ (instancetype)attributeWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new XML attribute.
*
* @param name The name of the attribute
* @param ns The namespace of the attribute
* @param stringValue The string value of the attribute
* @return A new autoreleased OFXMLAttribute with the specified parameters
*/
+ (instancetype)attributeWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLAttribute.
*
* @param name The name of the attribute
* @param stringValue The string value of the attribute
* @return An initialized OFXMLAttribute with the specified parameters
*/
- initWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLAttribute.
*
* @param name The name of the attribute
* @param ns The namespace of the attribute
* @param stringValue The string value of the attribute
* @return An initialized OFXMLAttribute with the specified parameters
*/
- initWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue;
/*!
* @brief Returns the name of the attribute as an autoreleased OFString.
*
* @return The name of the attribute as an autoreleased OFString
*/
|
<
|
<
|
<
<
|
|
|
|
|
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
|
/*!
* @brief A representation of an attribute of an XML element as an object.
*/
@interface OFXMLAttribute: OFXMLNode
{
@public
OFString *_name, *_namespace, *_stringValue;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy) OFString *name, *namespace, *stringValue;
#endif
/*!
* @brief Creates a new XML attribute.
*
* @param name The name of the attribute
* @param stringValue The string value of the attribute
* @return A new autoreleased OFXMLAttribute with the specified parameters
*/
+ (instancetype)attributeWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new XML attribute.
*
* @param name The name of the attribute
* @param namespace_ The namespace of the attribute
* @param stringValue The string value of the attribute
* @return A new autoreleased OFXMLAttribute with the specified parameters
*/
+ (instancetype)attributeWithName: (OFString*)name
namespace: (OFString*)namespace_
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLAttribute.
*
* @param name The name of the attribute
* @param stringValue The string value of the attribute
* @return An initialized OFXMLAttribute with the specified parameters
*/
- initWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLAttribute.
*
* @param name The name of the attribute
* @param namespace_ The namespace of the attribute
* @param stringValue The string value of the attribute
* @return An initialized OFXMLAttribute with the specified parameters
*/
- initWithName: (OFString*)name
namespace: (OFString*)namespace_
stringValue: (OFString*)stringValue;
/*!
* @brief Returns the name of the attribute as an autoreleased OFString.
*
* @return The name of the attribute as an autoreleased OFString
*/
|
︙ | | | ︙ | |
Modified src/OFXMLAttribute.m
from [39e877686b]
to [a242f67939].
︙ | | | ︙ | |
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
|
#import "OFInvalidArgumentException.h"
#import "autorelease.h"
#import "macros.h"
@implementation OFXMLAttribute
+ (instancetype)attributeWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue
{
return [[[self alloc] initWithName: name
namespace: ns
stringValue: stringValue] autorelease];
}
+ (instancetype)attributeWithName: (OFString*)name
stringValue: (OFString*)stringValue
{
return [[[self alloc] initWithName: name
stringValue: stringValue] autorelease];
}
- initWithName: (OFString*)name_
stringValue: (OFString*)stringValue_
{
return [self initWithName: name_
namespace: nil
stringValue: stringValue_];
}
- initWithName: (OFString*)name_
namespace: (OFString*)ns_
stringValue: (OFString*)stringValue_
{
self = [super init];
@try {
name = [name_ copy];
ns = [ns_ copy];
stringValue = [stringValue_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFInvalidArgumentException.h"
#import "autorelease.h"
#import "macros.h"
@implementation OFXMLAttribute
+ (instancetype)attributeWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue
{
return [[[self alloc] initWithName: name
namespace: namespace
stringValue: stringValue] autorelease];
}
+ (instancetype)attributeWithName: (OFString*)name
stringValue: (OFString*)stringValue
{
return [[[self alloc] initWithName: name
stringValue: stringValue] autorelease];
}
- initWithName: (OFString*)name
stringValue: (OFString*)stringValue
{
return [self initWithName: name
namespace: nil
stringValue: stringValue];
}
- initWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue
{
self = [super init];
@try {
_name = [name copy];
_namespace = [namespace copy];
_stringValue = [stringValue copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
name = [[[element attributeForName: @"name"] stringValue]
copy];
ns = [[[element attributeForName: @"namespace"] stringValue]
copy];
stringValue = [[[element attributeForName: @"stringValue"]
stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[name release];
[ns release];
[stringValue release];
[super dealloc];
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (OFString*)namespace
{
OF_GETTER(ns, YES)
}
- (OFString*)stringValue
{
OF_GETTER(stringValue, YES)
}
- (BOOL)isEqual: (id)object
{
OFXMLAttribute *otherAttribute;
if (![object isKindOfClass: [OFXMLAttribute class]])
return NO;
otherAttribute = object;
if (![otherAttribute->name isEqual: name])
return NO;
if (otherAttribute->ns != ns && ![otherAttribute->ns isEqual: ns])
return NO;
if (![otherAttribute->stringValue isEqual: stringValue])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [name hash]);
OF_HASH_ADD_HASH(hash, [ns hash]);
OF_HASH_ADD_HASH(hash, [stringValue hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFXMLElement*)XMLElementBySerializing
{
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
[element addAttributeWithName: @"name"
stringValue: name];
if (ns != nil)
[element addAttributeWithName: @"namespace"
stringValue: ns];
[element addAttributeWithName: @"stringValue"
stringValue: stringValue];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<OFXMLAttribute, name=%@, "
@"namespace=%@, stringValue=%@>",
name, ns, stringValue];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_name = [[[element attributeForName: @"name"]
stringValue] copy];
_namespace = [[[element attributeForName: @"namespace"]
stringValue] copy];
_stringValue = [[[element attributeForName: @"stringValue"]
stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_name release];
[_namespace release];
[_stringValue release];
[super dealloc];
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (OFString*)namespace
{
OF_GETTER(_namespace, YES)
}
- (OFString*)stringValue
{
OF_GETTER(_stringValue, YES)
}
- (BOOL)isEqual: (id)object
{
OFXMLAttribute *attribute;
if (![object isKindOfClass: [OFXMLAttribute class]])
return NO;
attribute = object;
if (![attribute->_name isEqual: _name])
return NO;
if (attribute->_namespace != _namespace &&
![attribute->_namespace isEqual: _namespace])
return NO;
if (![attribute->_stringValue isEqual: _stringValue])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_name hash]);
OF_HASH_ADD_HASH(hash, [_namespace hash]);
OF_HASH_ADD_HASH(hash, [_stringValue hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- (OFXMLElement*)XMLElementBySerializing
{
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
[element addAttributeWithName: @"name"
stringValue: _name];
if (_namespace != nil)
[element addAttributeWithName: @"namespace"
stringValue: _namespace];
[element addAttributeWithName: @"stringValue"
stringValue: _stringValue];
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<OFXMLAttribute, name=%@, "
@"namespace=%@, stringValue=%@>",
_name, _namespace, _stringValue];
}
@end
|
Modified src/OFXMLCDATA.h
from [9531b00aa3]
to [948e1d4299].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class representing XML CDATA.
*/
@interface OFXMLCDATA: OFXMLNode
{
OFString *CDATA;
}
/*!
* @brief Creates a new OFXMLCDATA with the specified string.
*
* @param string The string value for the CDATA
* @return A new OFXMLCDATA
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class representing XML CDATA.
*/
@interface OFXMLCDATA: OFXMLNode
{
OFString *_CDATA;
}
/*!
* @brief Creates a new OFXMLCDATA with the specified string.
*
* @param string The string value for the CDATA
* @return A new OFXMLCDATA
|
︙ | | | ︙ | |
Modified src/OFXMLCDATA.m
from [80501e221c]
to [3a90c3abbf].
︙ | | | ︙ | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
CDATA = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
_CDATA = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
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
119
120
121
122
123
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
CDATA = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLCDATA *otherCDATA;
if (![object isKindOfClass: [OFXMLCDATA class]])
return NO;
otherCDATA = object;
return ([otherCDATA->CDATA isEqual: CDATA]);
}
- (uint32_t)hash
{
return [CDATA hash];
}
- (OFString*)stringValue
{
return [[CDATA copy] autorelease];
}
- (OFString*)XMLString
{
return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<![CDATA[%@]]>", CDATA];
}
- (OFXMLElement*)XMLElementBySerializing
{
OFXMLElement *element =
[OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
[element addChild: self];
return element;
}
@end
|
|
|
|
|
|
|
>
|
|
|
|
|
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
119
120
121
122
123
124
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_CDATA = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLCDATA *CDATA;
if (![object isKindOfClass: [OFXMLCDATA class]])
return NO;
CDATA = object;
return ([CDATA->_CDATA isEqual: _CDATA]);
}
- (uint32_t)hash
{
return [_CDATA hash];
}
- (OFString*)stringValue
{
return [[_CDATA copy] autorelease];
}
- (OFString*)XMLString
{
/* FIXME: What to do about ]]>? */
return [OFString stringWithFormat: @"<![CDATA[%@]]>", _CDATA];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [self XMLString];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
return [self XMLString];
}
- (OFString*)description
{
return [self XMLString];
}
- (OFXMLElement*)XMLElementBySerializing
{
OFXMLElement *element =
[OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
[element addChild: self];
return element;
}
@end
|
Modified src/OFXMLCharacters.h
from [bad21294e1]
to [5d04d761e9].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class representing XML characters.
*/
@interface OFXMLCharacters: OFXMLNode
{
OFString *characters;
}
/*!
* @brief Creates a new OFXMLCharacters with the specified string.
*
* @param string The string value for the characters
* @return A new OFXMLCharacters
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class representing XML characters.
*/
@interface OFXMLCharacters: OFXMLNode
{
OFString *_characters;
}
/*!
* @brief Creates a new OFXMLCharacters with the specified string.
*
* @param string The string value for the characters
* @return A new OFXMLCharacters
|
︙ | | | ︙ | |
Modified src/OFXMLCharacters.m
from [d1e25b4850]
to [872a1be8d0].
︙ | | | ︙ | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
characters = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
_characters = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
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
119
120
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
characters = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLCharacters *otherCharacters;
if (![object isKindOfClass: [OFXMLCharacters class]])
return NO;
otherCharacters = object;
return ([otherCharacters->characters isEqual: characters]);
}
- (uint32_t)hash
{
return [characters hash];
}
- (OFString*)stringValue
{
return [[characters copy] autorelease];
}
- (OFString*)XMLString
{
return [characters stringByXMLEscaping];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [characters stringByXMLEscaping];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
return [characters stringByXMLEscaping];
}
- (OFString*)description
{
return [characters stringByXMLEscaping];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: characters];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_characters = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLCharacters *characters;
if (![object isKindOfClass: [OFXMLCharacters class]])
return NO;
characters = object;
return ([characters->_characters isEqual: _characters]);
}
- (uint32_t)hash
{
return [_characters hash];
}
- (OFString*)stringValue
{
return [[_characters copy] autorelease];
}
- (OFString*)XMLString
{
return [_characters stringByXMLEscaping];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [_characters stringByXMLEscaping];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
return [_characters stringByXMLEscaping];
}
- (OFString*)description
{
return [_characters stringByXMLEscaping];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: _characters];
}
@end
|
Modified src/OFXMLComment.h
from [8e29ccb3e9]
to [11e800d409].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class for representing XML comments.
*/
@interface OFXMLComment: OFXMLNode
{
OFString *comment;
}
/*!
* @brief Creates a new OFXMLComment with the specified string.
*
* @param string The string for the comment
* @return A new OFXMLComment
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class for representing XML comments.
*/
@interface OFXMLComment: OFXMLNode
{
OFString *_comment;
}
/*!
* @brief Creates a new OFXMLComment with the specified string.
*
* @param string The string for the comment
* @return A new OFXMLComment
|
︙ | | | ︙ | |
Modified src/OFXMLComment.m
from [4a37d9f4a6]
to [4d978dda45].
︙ | | | ︙ | |
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
comment = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
_comment = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
comment = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLComment *otherComment;
if (![object isKindOfClass: [OFXMLComment class]])
return NO;
otherComment = object;
return ([otherComment->comment isEqual: comment]);
}
- (uint32_t)hash
{
return [comment hash];
}
- (OFString*)stringValue
{
return @"";
}
- (OFString*)XMLString
{
return [OFString stringWithFormat: @"<!--%@-->", comment];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [OFString stringWithFormat: @"<!--%@-->", comment];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
OFString *ret;
if (indentation > 0 && level > 0) {
char *whitespaces = [self allocMemoryWithSize:
(level * indentation) + 1];
memset(whitespaces, ' ', level * indentation);
whitespaces[level * indentation] = 0;
@try {
ret = [OFString stringWithFormat: @"%s<!--%@-->",
whitespaces,
comment];
} @finally {
[self freeMemory: whitespaces];
}
} else
ret = [OFString stringWithFormat: @"<!--%@-->", comment];
return ret;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<!--%@-->", comment];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: comment];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_comment = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLComment *comment;
if (![object isKindOfClass: [OFXMLComment class]])
return NO;
comment = object;
return ([comment->_comment isEqual: _comment]);
}
- (uint32_t)hash
{
return [_comment hash];
}
- (OFString*)stringValue
{
return @"";
}
- (OFString*)XMLString
{
return [OFString stringWithFormat: @"<!--%@-->", _comment];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [OFString stringWithFormat: @"<!--%@-->", _comment];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
OFString *ret;
if (indentation > 0 && level > 0) {
char *whitespaces = [self allocMemoryWithSize:
(level * indentation) + 1];
memset(whitespaces, ' ', level * indentation);
whitespaces[level * indentation] = 0;
@try {
ret = [OFString stringWithFormat: @"%s<!--%@-->",
whitespaces,
_comment];
} @finally {
[self freeMemory: whitespaces];
}
} else
ret = [OFString stringWithFormat: @"<!--%@-->", _comment];
return ret;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<!--%@-->", _comment];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: _comment];
}
@end
|
Modified src/OFXMLElement+Serialization.m
from [ccf852396a]
to [4b7b970c65].
︙ | | | ︙ | |
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
@implementation OFXMLElement (Serialization)
- (id)objectByDeserializing
{
void *pool = objc_autoreleasePoolPush();
Class class;
id object;
if ((class = objc_getClass([name cStringWithEncoding:
OF_STRING_ENCODING_ASCII])) == Nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
if (![class conformsToProtocol: @protocol(OFSerialization)])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
|
|
|
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
@implementation OFXMLElement (Serialization)
- (id)objectByDeserializing
{
void *pool = objc_autoreleasePoolPush();
Class class;
id object;
if ((class = objc_getClass([_name cStringWithEncoding:
OF_STRING_ENCODING_ASCII])) == Nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
if (![class conformsToProtocol: @protocol(OFSerialization)])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]];
|
︙ | | | ︙ | |
Modified src/OFXMLElement.h
from [d1aca2d059]
to [ea560ddced].
︙ | | | ︙ | |
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
|
@class OFXMLAttribute;
/*!
* @brief A class which stores an XML element.
*/
@interface OFXMLElement: OFXMLNode
{
OFString *name;
OFString *ns;
OFString *defaultNamespace;
OFMutableArray *attributes;
OFMutableDictionary *namespaces;
OFMutableArray *children;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *name;
@property (copy, getter=namespace, setter=setNamespace:) OFString *ns;
@property (copy) OFString *defaultNamespace;
@property (readonly, copy) OFArray *attributes;
@property (readonly, copy) OFArray *children;
#endif
/*!
* @brief Creates a new XML element with the specified name.
*
* @param name The name for the element
* @return A new autoreleased OFXMLElement with the specified element name
|
<
|
<
|
|
|
|
<
<
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@class OFXMLAttribute;
/*!
* @brief A class which stores an XML element.
*/
@interface OFXMLElement: OFXMLNode
{
OFString *_name, *_namespace, *_defaultNamespace;
OFMutableArray *_attributes;
OFMutableDictionary *_namespaces;
OFMutableArray *_children;
}
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *name, *namespace, *defaultNamespace;
@property (readonly, copy) OFArray *attributes;
@property (copy) OFArray *children;
#endif
/*!
* @brief Creates a new XML element with the specified name.
*
* @param name The name for the element
* @return A new autoreleased OFXMLElement with the specified element name
|
︙ | | | ︙ | |
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
|
+ (instancetype)elementWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new XML element with the specified name and namespace.
*
* @param name The name for the element
* @param ns The namespace for the element
* @return A new autoreleased OFXMLElement with the specified element name and
* namespace
*/
+ (instancetype)elementWithName: (OFString*)name
namespace: (OFString*)ns;
/*!
* @brief Creates a new XML element with the specified name, namespace and
* string value.
*
* @param name The name for the element
* @param ns The namespace for the element
* @param stringValue The value for the element
* @return A new autoreleased OFXMLElement with the specified element name,
* namespace and value
*/
+ (instancetype)elementWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new element with the specified element.
*
* @param element An OFXMLElement to initialize the OFXMLElement with
* @return A new autoreleased OFXMLElement with the contents of the specified
|
|
|
|
|
|
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
|
+ (instancetype)elementWithName: (OFString*)name
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new XML element with the specified name and namespace.
*
* @param name The name for the element
* @param namespace The namespace for the element
* @return A new autoreleased OFXMLElement with the specified element name and
* namespace
*/
+ (instancetype)elementWithName: (OFString*)name
namespace: (OFString*)namespace;
/*!
* @brief Creates a new XML element with the specified name, namespace and
* string value.
*
* @param name The name for the element
* @param namespace The namespace for the element
* @param stringValue The value for the element
* @return A new autoreleased OFXMLElement with the specified element name,
* namespace and value
*/
+ (instancetype)elementWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue;
/*!
* @brief Creates a new element with the specified element.
*
* @param element An OFXMLElement to initialize the OFXMLElement with
* @return A new autoreleased OFXMLElement with the contents of the specified
|
︙ | | | ︙ | |
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified name
* and namespace.
*
* @param name The name for the element
* @param ns The namespace for the element
* @return An initialized OFXMLElement with the specified element name and
* namespace
*/
- initWithName: (OFString*)name
namespace: (OFString*)ns;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified name,
* namespace and value.
*
* @param name The name for the element
* @param ns The namespace for the element
* @param stringValue The value for the element
* @return An initialized OFXMLElement with the specified element name,
* namespace and value
*/
- initWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified
* element.
*
* @param element An OFXMLElement to initialize the OFXMLElement with
|
|
|
|
|
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified name
* and namespace.
*
* @param name The name for the element
* @param namespace The namespace for the element
* @return An initialized OFXMLElement with the specified element name and
* namespace
*/
- initWithName: (OFString*)name
namespace: (OFString*)namespace;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified name,
* namespace and value.
*
* @param name The name for the element
* @param namespace The namespace for the element
* @param stringValue The value for the element
* @return An initialized OFXMLElement with the specified element name,
* namespace and value
*/
- initWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue;
/*!
* @brief Initializes an already allocated OFXMLElement with the specified
* element.
*
* @param element An OFXMLElement to initialize the OFXMLElement with
|
︙ | | | ︙ | |
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
* @return The name of the element
*/
- (OFString*)name;
/*!
* @brief Sets the namespace of the element.
*
* @param ns The new namespace
*/
- (void)setNamespace: (OFString*)ns;
/*!
* @brief Returns the namespace of the element.
*
* @return The namespace of the element
*/
- (OFString*)namespace;
|
|
|
|
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
* @return The name of the element
*/
- (OFString*)name;
/*!
* @brief Sets the namespace of the element.
*
* @param namespace The new namespace
*/
- (void)setNamespace: (OFString*)namespace;
/*!
* @brief Returns the namespace of the element.
*
* @return The namespace of the element
*/
- (OFString*)namespace;
|
︙ | | | ︙ | |
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
* @brief Adds the specified attribute with the specified namespace and string
* value.
*
* If an attribute with the same name and namespace already exists, it is not
* added.
*
* @param name The name of the attribute
* @param ns The namespace of the attribute
* @param stringValue The value of the attribute
*/
- (void)addAttributeWithName: (OFString*)name
namespace: (OFString*)ns
stringValue: (OFString*)stringValue;
/*!
* @brief Returns the attribute with the specified name.
*
* @param attributeName The name of the attribute
* @return The attribute with the specified name
|
|
|
|
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
* @brief Adds the specified attribute with the specified namespace and string
* value.
*
* If an attribute with the same name and namespace already exists, it is not
* added.
*
* @param name The name of the attribute
* @param namespace The namespace of the attribute
* @param stringValue The value of the attribute
*/
- (void)addAttributeWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue;
/*!
* @brief Returns the attribute with the specified name.
*
* @param attributeName The name of the attribute
* @return The attribute with the specified name
|
︙ | | | ︙ | |
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
- (void)removeAttributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS;
/*!
* @brief Sets a prefix for a namespace.
*
* @param prefix The prefix for the namespace
* @param ns The namespace for which the prefix is set
*/
- (void)setPrefix: (OFString*)prefix
forNamespace: (OFString*)ns;
/*!
* @brief Binds a prefix for a namespace.
*
* @param prefix The prefix for the namespace
* @param ns The namespace for which the prefix is bound
*/
- (void)bindPrefix: (OFString*)prefix
forNamespace: (OFString*)ns;
/*!
* @brief Sets the default namespace for the element to be used if there is no
* parent.
*
* @param ns The default namespace for the element
*/
- (void)setDefaultNamespace: (OFString*)ns;
/*!
* @brief Adds a child to the OFXMLElement.
*
* @param child An OFXMLNode which is added as a child
*/
- (void)addChild: (OFXMLNode*)child;
|
|
|
|
|
|
|
|
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
|
- (void)removeAttributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS;
/*!
* @brief Sets a prefix for a namespace.
*
* @param prefix The prefix for the namespace
* @param namespace The namespace for which the prefix is set
*/
- (void)setPrefix: (OFString*)prefix
forNamespace: (OFString*)namespace;
/*!
* @brief Binds a prefix for a namespace.
*
* @param prefix The prefix for the namespace
* @param namespace The namespace for which the prefix is bound
*/
- (void)bindPrefix: (OFString*)prefix
forNamespace: (OFString*)namespace;
/*!
* @brief Sets the default namespace for the element to be used if there is no
* parent.
*
* @param defaultNamespace The default namespace for the element
*/
- (void)setDefaultNamespace: (OFString*)defaultNamespace;
/*!
* @brief Adds a child to the OFXMLElement.
*
* @param child An OFXMLNode which is added as a child
*/
- (void)addChild: (OFXMLNode*)child;
|
︙ | | | ︙ | |
Modified src/OFXMLElement.m
from [5e664c8a15]
to [177671f0ee].
︙ | | | ︙ | |
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
|
static Class charactersClass = Nil;
static Class CDATAClass = Nil;
@interface OFXMLElement_OFXMLElementBuilderDelegate: OFObject
{
@public
OFXMLElement *element;
}
@end
@implementation OFXMLElement_OFXMLElementBuilderDelegate
- (void)elementBuilder: (OFXMLElementBuilder*)builder
didBuildElement: (OFXMLElement*)element_
{
if (element == nil)
element = [element_ retain];
}
- (void)dealloc
{
[element release];
[super dealloc];
}
@end
@implementation OFXMLElement
+ (void)initialize
|
|
|
|
|
|
|
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
|
static Class charactersClass = Nil;
static Class CDATAClass = Nil;
@interface OFXMLElement_OFXMLElementBuilderDelegate: OFObject
{
@public
OFXMLElement *_element;
}
@end
@implementation OFXMLElement_OFXMLElementBuilderDelegate
- (void)elementBuilder: (OFXMLElementBuilder*)builder
didBuildElement: (OFXMLElement*)element
{
if (_element == nil)
_element = [element retain];
}
- (void)dealloc
{
[_element release];
[super dealloc];
}
@end
@implementation OFXMLElement
+ (void)initialize
|
︙ | | | ︙ | |
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
[self release];
@throw e;
}
abort();
}
- initWithName: (OFString*)name_
{
return [self initWithName: name_
namespace: nil
stringValue: nil];
}
- initWithName: (OFString*)name_
stringValue: (OFString*)stringValue
{
return [self initWithName: name_
namespace: nil
stringValue: stringValue];
}
- initWithName: (OFString*)name_
namespace: (OFString*)ns_
{
return [self initWithName: name_
namespace: ns_
stringValue: nil];
}
- initWithName: (OFString*)name_
namespace: (OFString*)ns_
stringValue: (OFString*)stringValue
{
self = [super init];
@try {
if (name_ == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
name = [name_ copy];
ns = [ns_ copy];
namespaces = [[OFMutableDictionary alloc]
initWithKeysAndObjects:
@"http://www.w3.org/XML/1998/namespace", @"xml",
@"http://www.w3.org/2000/xmlns/", @"xmlns", nil];
if (stringValue != nil)
[self setStringValue: stringValue];
} @catch (id e) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
[self release];
@throw e;
}
abort();
}
- initWithName: (OFString*)name
{
return [self initWithName: name
namespace: nil
stringValue: nil];
}
- initWithName: (OFString*)name
stringValue: (OFString*)stringValue
{
return [self initWithName: name
namespace: nil
stringValue: stringValue];
}
- initWithName: (OFString*)name
namespace: (OFString*)namespace
{
return [self initWithName: name
namespace: namespace
stringValue: nil];
}
- initWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue
{
self = [super init];
@try {
if (name == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_name = [name copy];
_namespace = [namespace copy];
_namespaces = [[OFMutableDictionary alloc]
initWithKeysAndObjects:
@"http://www.w3.org/XML/1998/namespace", @"xml",
@"http://www.w3.org/2000/xmlns/", @"xmlns", nil];
if (stringValue != nil)
[self setStringValue: stringValue];
} @catch (id e) {
|
︙ | | | ︙ | |
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
@try {
if (element == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
name = [element->name copy];
ns = [element->ns copy];
defaultNamespace = [element->defaultNamespace copy];
attributes = [element->attributes mutableCopy];
namespaces = [element->namespaces mutableCopy];
children = [element->children mutableCopy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
|
|
|
|
|
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
@try {
if (element == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_name = [element->_name copy];
_namespace = [element->_namespace copy];
_defaultNamespace = [element->_defaultNamespace copy];
_attributes = [element->_attributes mutableCopy];
_namespaces = [element->_namespaces mutableCopy];
_children = [element->_children mutableCopy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
[parser parseString: string];
if (![parser finishedParsing])
@throw [OFMalformedXMLException exceptionWithClass: c
parser: parser];
self = [delegate->element retain];
objc_autoreleasePoolPop(pool);
return self;
}
- initWithFile: (OFString*)path
|
|
|
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
[parser parseString: string];
if (![parser finishedParsing])
@throw [OFMalformedXMLException exceptionWithClass: c
parser: parser];
self = [delegate->_element retain];
objc_autoreleasePoolPop(pool);
return self;
}
- initWithFile: (OFString*)path
|
︙ | | | ︙ | |
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
[parser parseFile: path];
if (![parser finishedParsing])
@throw [OFMalformedXMLException exceptionWithClass: c
parser: parser];
self = [delegate->element retain];
objc_autoreleasePoolPop(pool);
return self;
}
- initWithSerialization: (OFXMLElement*)element
|
|
|
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
[parser parseFile: path];
if (![parser finishedParsing])
@throw [OFMalformedXMLException exceptionWithClass: c
parser: parser];
self = [delegate->_element retain];
objc_autoreleasePoolPop(pool);
return self;
}
- initWithSerialization: (OFXMLElement*)element
|
︙ | | | ︙ | |
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
name = [[[element attributeForName: @"name"] stringValue] copy];
ns = [[[element attributeForName: @"namespace"] stringValue]
copy];
defaultNamespace = [[[element attributeForName:
@"defaultNamespace"] stringValue] copy];
attributesElement = [[[element
elementForName: @"attributes"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
namespacesElement = [[[element
elementForName: @"namespaces"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
childrenElement = [[[element
elementForName: @"children"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
attributes = [[attributesElement objectByDeserializing]
mutableCopy];
namespaces = [[namespacesElement objectByDeserializing]
mutableCopy];
children = [[childrenElement objectByDeserializing]
mutableCopy];
/* Sanity checks */
if ((attributes != nil &&
![attributes isKindOfClass: [OFMutableArray class]]) ||
(namespaces != nil &&
![namespaces isKindOfClass: [OFMutableDictionary class]]) ||
(children != nil &&
![children isKindOfClass: [OFMutableArray class]]))
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objectEnumerator = [attributes objectEnumerator];
while ((object = [objectEnumerator nextObject]) != nil)
if (![object isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
keyEnumerator = [namespaces keyEnumerator];
objectEnumerator = [namespaces objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
if (![key isKindOfClass: [OFString class]] ||
![object isKindOfClass: [OFString class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objectEnumerator = [children objectEnumerator];
while ((object = [objectEnumerator nextObject]) != nil)
if (![object isKindOfClass: [OFXMLNode class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (namespaces == nil)
namespaces = [[OFMutableDictionary alloc] init];
[namespaces setObject: @"xml"
forKey: @"http://www.w3.org/XML/1998/namespace"];
[namespaces setObject: @"xmlns"
forKey: @"http://www.w3.org/2000/xmlns/"];
if (name == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)setName: (OFString*)name_
{
if (name_ == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(name, name_, YES, 1)
}
- (OFString*)name
{
OF_GETTER(name, YES)
}
- (void)setNamespace: (OFString*)ns_
{
OF_SETTER(ns, ns_, YES, 1)
}
- (OFString*)namespace
{
OF_GETTER(ns, YES)
}
- (OFArray*)attributes
{
OF_GETTER(attributes, YES)
}
- (void)setChildren: (OFArray*)children_
{
OF_SETTER(children, children_, YES, 2)
}
- (OFArray*)children
{
OF_GETTER(children, YES)
}
- (void)setStringValue: (OFString*)stringValue
{
void *pool = objc_autoreleasePoolPush();
[self setChildren: [OFArray arrayWithObject:
[OFXMLCharacters charactersWithString: stringValue]]];
objc_autoreleasePoolPop(pool);
}
- (OFString*)stringValue
{
OFMutableString *ret;
OFXMLElement **objects;
size_t i, count = [children count];
if (count == 0)
return @"";
ret = [OFMutableString string];
objects = [children objects];
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[ret appendString: [objects[i] stringValue]];
objc_autoreleasePoolPop(pool);
|
|
>
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_name = [[[element attributeForName: @"name"]
stringValue] copy];
_namespace = [[[element attributeForName: @"namespace"]
stringValue] copy];
_defaultNamespace = [[[element attributeForName:
@"defaultNamespace"] stringValue] copy];
attributesElement = [[[element
elementForName: @"attributes"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
namespacesElement = [[[element
elementForName: @"namespaces"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
childrenElement = [[[element
elementForName: @"children"
namespace: OF_SERIALIZATION_NS] elementsForNamespace:
OF_SERIALIZATION_NS] firstObject];
_attributes = [[attributesElement objectByDeserializing]
mutableCopy];
_namespaces = [[namespacesElement objectByDeserializing]
mutableCopy];
_children = [[childrenElement objectByDeserializing]
mutableCopy];
/* Sanity checks */
if ((_attributes != nil && ![_attributes isKindOfClass:
[OFMutableArray class]]) || (_namespaces != nil &&
![_namespaces isKindOfClass:
[OFMutableDictionary class]]) || (_children != nil &&
![_children isKindOfClass: [OFMutableArray class]]))
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objectEnumerator = [_attributes objectEnumerator];
while ((object = [objectEnumerator nextObject]) != nil)
if (![object isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
keyEnumerator = [_namespaces keyEnumerator];
objectEnumerator = [_namespaces objectEnumerator];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
if (![key isKindOfClass: [OFString class]] ||
![object isKindOfClass: [OFString class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objectEnumerator = [_children objectEnumerator];
while ((object = [objectEnumerator nextObject]) != nil)
if (![object isKindOfClass: [OFXMLNode class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (_namespaces == nil)
_namespaces = [[OFMutableDictionary alloc] init];
[_namespaces
setObject: @"xml"
forKey: @"http://www.w3.org/XML/1998/namespace"];
[_namespaces setObject: @"xmlns"
forKey: @"http://www.w3.org/2000/xmlns/"];
if (_name == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_name release];
[_namespace release];
[_defaultNamespace release];
[_attributes release];
[_namespaces release];
[_children release];
[super dealloc];
}
- (void)setName: (OFString*)name
{
if (name == nil)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
OF_SETTER(_name, name, YES, 1)
}
- (OFString*)name
{
OF_GETTER(_name, YES)
}
- (void)setNamespace: (OFString*)namespace
{
OF_SETTER(_namespace, namespace, YES, 1)
}
- (OFString*)namespace
{
OF_GETTER(_namespace, YES)
}
- (OFArray*)attributes
{
OF_GETTER(_attributes, YES)
}
- (void)setChildren: (OFArray*)children
{
OF_SETTER(_children, children, YES, 2)
}
- (OFArray*)children
{
OF_GETTER(_children, YES)
}
- (void)setStringValue: (OFString*)stringValue
{
void *pool = objc_autoreleasePoolPush();
[self setChildren: [OFArray arrayWithObject:
[OFXMLCharacters charactersWithString: stringValue]]];
objc_autoreleasePoolPop(pool);
}
- (OFString*)stringValue
{
OFMutableString *ret;
OFXMLElement **objects;
size_t i, count = [_children count];
if (count == 0)
return @"";
ret = [OFMutableString string];
objects = [_children objects];
for (i = 0; i < count; i++) {
void *pool = objc_autoreleasePoolPush();
[ret appendString: [objects[i] stringValue]];
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
|
OFXMLAttribute **attributesObjects;
OFString *ret;
OFString *defaultNS;
pool = objc_autoreleasePoolPush();
parentPrefix = [allNamespaces objectForKey:
(parent != nil && parent->ns != nil ? parent->ns : (OFString*)@"")];
/* Add the namespaces of the current element */
if (allNamespaces != nil) {
OFEnumerator *keyEnumerator = [namespaces keyEnumerator];
OFEnumerator *objectEnumerator = [namespaces objectEnumerator];
OFMutableDictionary *tmp;
id key, object;
tmp = [[allNamespaces mutableCopy] autorelease];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[tmp setObject: object
forKey: key];
allNamespaces = tmp;
} else
allNamespaces = namespaces;
prefix = [allNamespaces objectForKey:
(ns != nil ? ns : (OFString*)@"")];
if (parent != nil && parent->ns != nil && parentPrefix == nil)
defaultNS = parent->ns;
else if (parent != nil && parent->defaultNamespace != nil)
defaultNS = parent->defaultNamespace;
else
defaultNS = defaultNamespace;
i = 0;
length = [name UTF8StringLength] + 3 + (level * indentation);
cString = [self allocMemoryWithSize: length];
memset(cString + i, ' ', level * indentation);
i += level * indentation;
/* Start of tag */
cString[i++] = '<';
if (prefix != nil && ![ns isEqual: defaultNS]) {
length += [prefix UTF8StringLength] + 1;
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
}
memcpy(cString + i, [prefix UTF8String],
[prefix UTF8StringLength]);
i += [prefix UTF8StringLength];
cString[i++] = ':';
}
memcpy(cString + i, [name UTF8String], [name UTF8StringLength]);
i += [name UTF8StringLength];
/* xmlns if necessary */
if (prefix == nil && ((ns != nil && ![ns isEqual: defaultNS]) ||
(ns == nil && defaultNS != nil))) {
length += [ns UTF8StringLength] + 9;
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
}
memcpy(cString + i, " xmlns='", 8);
i += 8;
memcpy(cString + i, [ns UTF8String], [ns UTF8StringLength]);
i += [ns UTF8StringLength];
cString[i++] = '\'';
}
/* Attributes */
attributesObjects = [attributes objects];
attributesCount = [attributes count];
for (j = 0; j < attributesCount; j++) {
void *pool2 = objc_autoreleasePoolPush();
OFString *attributeName = [attributesObjects[j] name];
OFString *attributePrefix = nil;
OFString *tmp =
[[attributesObjects[j] stringValue] stringByXMLEscaping];
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
>
|
|
|
|
|
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
|
OFXMLAttribute **attributesObjects;
OFString *ret;
OFString *defaultNS;
pool = objc_autoreleasePoolPush();
parentPrefix = [allNamespaces objectForKey:
(parent != nil && parent->_namespace != nil
? parent->_namespace : (OFString*)@"")];
/* Add the namespaces of the current element */
if (allNamespaces != nil) {
OFEnumerator *keyEnumerator = [_namespaces keyEnumerator];
OFEnumerator *objectEnumerator = [_namespaces objectEnumerator];
OFMutableDictionary *tmp;
id key, object;
tmp = [[allNamespaces mutableCopy] autorelease];
while ((key = [keyEnumerator nextObject]) != nil &&
(object = [objectEnumerator nextObject]) != nil)
[tmp setObject: object
forKey: key];
allNamespaces = tmp;
} else
allNamespaces = _namespaces;
prefix = [allNamespaces objectForKey:
(_namespace != nil ? _namespace : (OFString*)@"")];
if (parent != nil && parent->_namespace != nil && parentPrefix == nil)
defaultNS = parent->_namespace;
else if (parent != nil && parent->_defaultNamespace != nil)
defaultNS = parent->_defaultNamespace;
else
defaultNS = _defaultNamespace;
i = 0;
length = [_name UTF8StringLength] + 3 + (level * indentation);
cString = [self allocMemoryWithSize: length];
memset(cString + i, ' ', level * indentation);
i += level * indentation;
/* Start of tag */
cString[i++] = '<';
if (prefix != nil && ![_namespace isEqual: defaultNS]) {
length += [prefix UTF8StringLength] + 1;
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
}
memcpy(cString + i, [prefix UTF8String],
[prefix UTF8StringLength]);
i += [prefix UTF8StringLength];
cString[i++] = ':';
}
memcpy(cString + i, [_name UTF8String], [_name UTF8StringLength]);
i += [_name UTF8StringLength];
/* xmlns if necessary */
if (prefix == nil && ((_namespace != nil &&
![_namespace isEqual: defaultNS]) ||
(_namespace == nil && defaultNS != nil))) {
length += [_namespace UTF8StringLength] + 9;
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
}
memcpy(cString + i, " xmlns='", 8);
i += 8;
memcpy(cString + i, [_namespace UTF8String],
[_namespace UTF8StringLength]);
i += [_namespace UTF8StringLength];
cString[i++] = '\'';
}
/* Attributes */
attributesObjects = [_attributes objects];
attributesCount = [_attributes count];
for (j = 0; j < attributesCount; j++) {
void *pool2 = objc_autoreleasePoolPush();
OFString *attributeName = [attributesObjects[j] name];
OFString *attributePrefix = nil;
OFString *tmp =
[[attributesObjects[j] stringValue] stringByXMLEscaping];
|
︙ | | | ︙ | |
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
|
i += [tmp UTF8StringLength];
cString[i++] = '\'';
objc_autoreleasePoolPop(pool2);
}
/* Childen */
if (children != nil) {
OFXMLElement **childrenObjects = [children objects];
size_t childrenCount = [children count];
OFDataArray *tmp = [OFDataArray dataArray];
BOOL indent;
if (indentation > 0) {
indent = YES;
for (j = 0; j < childrenCount; j++) {
|
|
|
|
|
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
|
i += [tmp UTF8StringLength];
cString[i++] = '\'';
objc_autoreleasePoolPop(pool2);
}
/* Childen */
if (_children != nil) {
OFXMLElement **childrenObjects = [_children objects];
size_t childrenCount = [_children count];
OFDataArray *tmp = [OFDataArray dataArray];
BOOL indent;
if (indentation > 0) {
indent = YES;
for (j = 0; j < childrenCount; j++) {
|
︙ | | | ︙ | |
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
|
[tmp addItems: [child UTF8String]
count: [child UTF8StringLength]];
}
if (indent)
[tmp addItem: "\n"];
length += [tmp count] + [name UTF8StringLength] + 2 +
(indent ? level * indentation : 0);
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
|
|
|
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
|
[tmp addItems: [child UTF8String]
count: [child UTF8StringLength]];
}
if (indent)
[tmp addItem: "\n"];
length += [tmp count] + [_name UTF8StringLength] + 2 +
(indent ? level * indentation : 0);
@try {
cString = [self resizeMemory: cString
size: length];
} @catch (id e) {
[self freeMemory: cString];
@throw e;
|
︙ | | | ︙ | |
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
|
}
memcpy(cString + i, [prefix UTF8String],
[prefix UTF8StringLength]);
i += [prefix UTF8StringLength];
cString[i++] = ':';
}
memcpy(cString + i, [name UTF8String], [name UTF8StringLength]);
i += [name UTF8StringLength];
} else
cString[i++] = '/';
cString[i++] = '>';
assert(i == length);
objc_autoreleasePoolPop(pool);
|
|
|
>
|
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
|
}
memcpy(cString + i, [prefix UTF8String],
[prefix UTF8StringLength]);
i += [prefix UTF8StringLength];
cString[i++] = ':';
}
memcpy(cString + i, [_name UTF8String],
[_name UTF8StringLength]);
i += [_name UTF8StringLength];
} else
cString[i++] = '/';
cString[i++] = '>';
assert(i == length);
objc_autoreleasePoolPop(pool);
|
︙ | | | ︙ | |
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
|
{
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
if (name != nil)
[element addAttributeWithName: @"name"
stringValue: name];
if (ns != nil)
[element addAttributeWithName: @"namespace"
stringValue: ns];
if (defaultNamespace != nil)
[element addAttributeWithName: @"defaultNamespace"
stringValue: defaultNamespace];
if (attributes != nil) {
OFXMLElement *attributesElement;
attributesElement =
[OFXMLElement elementWithName: @"attributes"
namespace: OF_SERIALIZATION_NS];
[attributesElement addChild:
[attributes XMLElementBySerializing]];
[element addChild: attributesElement];
}
if (namespaces != nil) {
OFXMLElement *namespacesElement;
OFMutableDictionary *namespacesCopy =
[[namespaces mutableCopy] autorelease];
[namespacesCopy removeObjectForKey:
@"http://www.w3.org/XML/1998/namespace"];
[namespacesCopy removeObjectForKey:
@"http://www.w3.org/2000/xmlns/"];
if ([namespacesCopy count] > 0) {
namespacesElement =
[OFXMLElement elementWithName: @"namespaces"
namespace: OF_SERIALIZATION_NS];
[namespacesElement addChild:
[namespacesCopy XMLElementBySerializing]];
[element addChild: namespacesElement];
}
}
if (children != nil) {
OFXMLElement *childrenElement;
childrenElement =
[OFXMLElement elementWithName: @"children"
namespace: OF_SERIALIZATION_NS];
[childrenElement addChild: [children XMLElementBySerializing]];
[element addChild: childrenElement];
}
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (void)addAttribute: (OFXMLAttribute*)attribute
{
if (attributes == nil)
attributes = [[OFMutableArray alloc] init];
if ([self attributeForName: attribute->name
namespace: attribute->ns] == nil)
[attributes addObject: attribute];
}
- (void)addAttributeWithName: (OFString*)name_
stringValue: (OFString*)stringValue
{
[self addAttributeWithName: name_
namespace: nil
stringValue: stringValue];
}
- (void)addAttributeWithName: (OFString*)name_
namespace: (OFString*)ns_
stringValue: (OFString*)stringValue
{
void *pool = objc_autoreleasePoolPush();
[self addAttribute: [OFXMLAttribute attributeWithName: name_
namespace: ns_
stringValue: stringValue]];
objc_autoreleasePoolPop(pool);
}
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
{
OFXMLAttribute **objects = [attributes objects];
size_t i, count = [attributes count];
for (i = 0; i < count; i++)
if (objects[i]->ns == nil &&
[objects[i]->name isEqual: attributeName])
return [[objects[i] retain] autorelease];
return nil;
}
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS
{
OFXMLAttribute **objects;
size_t i, count;
if (attributeNS == nil)
return [self attributeForName: attributeName];
objects = [attributes objects];
count = [attributes count];
for (i = 0; i < count; i++)
if ([objects[i]->ns isEqual: attributeNS] &&
[objects[i]->name isEqual: attributeName])
return [[objects[i] retain] autorelease];
return nil;
}
- (void)removeAttributeForName: (OFString*)attributeName
{
OFXMLAttribute **objects = [attributes objects];
size_t i, count = [attributes count];
for (i = 0; i < count; i++) {
if (objects[i]->ns == nil &&
[objects[i]->name isEqual: attributeName]) {
[attributes removeObjectAtIndex: i];
return;
}
}
}
- (void)removeAttributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS
{
OFXMLAttribute **objects;
size_t i, count;
if (attributeNS == nil)
return [self removeAttributeForName: attributeName];
objects = [attributes objects];
count = [attributes count];
for (i = 0; i < count; i++) {
if ([objects[i]->ns isEqual: attributeNS] &&
[objects[i]->name isEqual: attributeName]) {
[attributes removeObjectAtIndex: i];
return;
}
}
}
- (void)setPrefix: (OFString*)prefix
forNamespace: (OFString*)ns_
{
if ([prefix length] == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (ns_ == nil)
ns_ = @"";
[namespaces setObject: prefix
forKey: ns_];
}
- (void)bindPrefix: (OFString*)prefix
forNamespace: (OFString*)ns_
{
[self setPrefix: prefix
forNamespace: ns_];
[self addAttributeWithName: prefix
namespace: @"http://www.w3.org/2000/xmlns/"
stringValue: ns_];
}
- (OFString*)defaultNamespace
{
OF_GETTER(defaultNamespace, YES)
}
- (void)setDefaultNamespace: (OFString*)ns_
{
OF_SETTER(defaultNamespace, ns_, YES, 1)
}
- (void)addChild: (OFXMLNode*)child
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (children == nil)
children = [[OFMutableArray alloc] init];
[children addObject: child];
}
- (void)insertChild: (OFXMLNode*)child
atIndex: (size_t)index
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (children == nil)
children = [[OFMutableArray alloc] init];
[children insertObject: child
atIndex: index];
}
- (void)insertChildren: (OFArray*)children_
atIndex: (size_t)index
{
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator = [children_ objectEnumerator];
OFXMLNode *node;
while ((node = [enumerator nextObject]) != nil)
if ([node isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[children insertObjectsFromArray: children_
atIndex: index];
objc_autoreleasePoolPop(pool);
}
- (void)removeChild: (OFXMLNode*)child
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[children removeObject: child];
}
- (void)removeChildAtIndex: (size_t)index
{
[children removeObjectAtIndex: index];
}
- (void)replaceChild: (OFXMLNode*)child
withNode: (OFXMLNode*)node
{
if ([node isKindOfClass: [OFXMLAttribute class]] ||
[child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[children replaceObject: child
withObject: node];
}
- (void)replaceChildAtIndex: (size_t)index
withNode: (OFXMLNode*)node
{
if ([node isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[children replaceObjectAtIndex: index
withObject: node];
}
- (OFXMLElement*)elementForName: (OFString*)elementName
{
return [[self elementsForName: elementName] firstObject];
}
- (OFXMLElement*)elementForName: (OFString*)elementName
namespace: (OFString*)elementNS
{
return [[self elementsForName: elementName
namespace: elementNS] firstObject];
}
- (OFArray*)elements
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [children objects];
size_t i, count = [children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForName: (OFString*)elementName
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [children objects];
size_t i, count = [children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
objects[i]->ns == nil &&
[objects[i]->name isEqual: elementName])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForNamespace: (OFString*)elementNS
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [children objects];
size_t i, count = [children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
objects[i]->name != nil &&
[objects[i]->ns isEqual: elementNS])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForName: (OFString*)elementName
namespace: (OFString*)elementNS
{
OFMutableArray *ret;
OFXMLElement **objects;
size_t i, count;
if (elementNS == nil)
return [self elementsForName: elementName];
ret = [OFMutableArray array];
objects = [children objects];
count = [children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
[objects[i]->ns isEqual: elementNS] &&
[objects[i]->name isEqual: elementName])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (BOOL)isEqual: (id)object
{
OFXMLElement *otherElement;
if (![object isKindOfClass: [OFXMLElement class]])
return NO;
otherElement = object;
if (otherElement->name != name && ![otherElement->name isEqual: name])
return NO;
if (otherElement->ns != ns && ![otherElement->ns isEqual: ns])
return NO;
if (otherElement->defaultNamespace != defaultNamespace &&
![otherElement->defaultNamespace isEqual: defaultNamespace])
return NO;
if (otherElement->attributes != attributes &&
![otherElement->attributes isEqual: attributes])
return NO;
if (otherElement->namespaces != namespaces &&
![otherElement->namespaces isEqual: namespaces])
return NO;
if (otherElement->children != children &&
![otherElement->children isEqual: children])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [name hash]);
OF_HASH_ADD_HASH(hash, [ns hash]);
OF_HASH_ADD_HASH(hash, [defaultNamespace hash]);
OF_HASH_ADD_HASH(hash, [attributes hash]);
OF_HASH_ADD_HASH(hash, [namespaces hash]);
OF_HASH_ADD_HASH(hash, [children hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- copy
{
return [[[self class] alloc] initWithElement: self];
}
- (void)dealloc
{
[name release];
[ns release];
[defaultNamespace release];
[attributes release];
[namespaces release];
[children release];
[super dealloc];
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
|
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
|
{
void *pool = objc_autoreleasePoolPush();
OFXMLElement *element;
element = [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS];
if (_name != nil)
[element addAttributeWithName: @"name"
stringValue: _name];
if (_namespace != nil)
[element addAttributeWithName: @"namespace"
stringValue: _namespace];
if (_defaultNamespace != nil)
[element addAttributeWithName: @"defaultNamespace"
stringValue: _defaultNamespace];
if (_attributes != nil) {
OFXMLElement *attributesElement;
attributesElement =
[OFXMLElement elementWithName: @"attributes"
namespace: OF_SERIALIZATION_NS];
[attributesElement addChild:
[_attributes XMLElementBySerializing]];
[element addChild: attributesElement];
}
if (_namespaces != nil) {
OFXMLElement *namespacesElement;
OFMutableDictionary *namespacesCopy =
[[_namespaces mutableCopy] autorelease];
[namespacesCopy removeObjectForKey:
@"http://www.w3.org/XML/1998/namespace"];
[namespacesCopy removeObjectForKey:
@"http://www.w3.org/2000/xmlns/"];
if ([namespacesCopy count] > 0) {
namespacesElement =
[OFXMLElement elementWithName: @"namespaces"
namespace: OF_SERIALIZATION_NS];
[namespacesElement addChild:
[namespacesCopy XMLElementBySerializing]];
[element addChild: namespacesElement];
}
}
if (_children != nil) {
OFXMLElement *childrenElement;
childrenElement =
[OFXMLElement elementWithName: @"children"
namespace: OF_SERIALIZATION_NS];
[childrenElement addChild: [_children XMLElementBySerializing]];
[element addChild: childrenElement];
}
[element retain];
objc_autoreleasePoolPop(pool);
return [element autorelease];
}
- (void)addAttribute: (OFXMLAttribute*)attribute
{
if (_attributes == nil)
_attributes = [[OFMutableArray alloc] init];
if ([self attributeForName: attribute->_name
namespace: attribute->_namespace] == nil)
[_attributes addObject: attribute];
}
- (void)addAttributeWithName: (OFString*)name
stringValue: (OFString*)stringValue
{
[self addAttributeWithName: name
namespace: nil
stringValue: stringValue];
}
- (void)addAttributeWithName: (OFString*)name
namespace: (OFString*)namespace
stringValue: (OFString*)stringValue
{
void *pool = objc_autoreleasePoolPush();
[self addAttribute: [OFXMLAttribute attributeWithName: name
namespace: namespace
stringValue: stringValue]];
objc_autoreleasePoolPop(pool);
}
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
{
OFXMLAttribute **objects = [_attributes objects];
size_t i, count = [_attributes count];
for (i = 0; i < count; i++)
if (objects[i]->_namespace == nil &&
[objects[i]->_name isEqual: attributeName])
return [[objects[i] retain] autorelease];
return nil;
}
- (OFXMLAttribute*)attributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS
{
OFXMLAttribute **objects;
size_t i, count;
if (attributeNS == nil)
return [self attributeForName: attributeName];
objects = [_attributes objects];
count = [_attributes count];
for (i = 0; i < count; i++)
if ([objects[i]->_namespace isEqual: attributeNS] &&
[objects[i]->_name isEqual: attributeName])
return [[objects[i] retain] autorelease];
return nil;
}
- (void)removeAttributeForName: (OFString*)attributeName
{
OFXMLAttribute **objects = [_attributes objects];
size_t i, count = [_attributes count];
for (i = 0; i < count; i++) {
if (objects[i]->_namespace == nil &&
[objects[i]->_name isEqual: attributeName]) {
[_attributes removeObjectAtIndex: i];
return;
}
}
}
- (void)removeAttributeForName: (OFString*)attributeName
namespace: (OFString*)attributeNS
{
OFXMLAttribute **objects;
size_t i, count;
if (attributeNS == nil)
return [self removeAttributeForName: attributeName];
objects = [_attributes objects];
count = [_attributes count];
for (i = 0; i < count; i++) {
if ([objects[i]->_namespace isEqual: attributeNS] &&
[objects[i]->_name isEqual: attributeName]) {
[_attributes removeObjectAtIndex: i];
return;
}
}
}
- (void)setPrefix: (OFString*)prefix
forNamespace: (OFString*)namespace
{
if ([prefix length] == 0)
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (namespace == nil)
namespace = @"";
[_namespaces setObject: prefix
forKey: namespace];
}
- (void)bindPrefix: (OFString*)prefix
forNamespace: (OFString*)namespace
{
[self setPrefix: prefix
forNamespace: namespace];
[self addAttributeWithName: prefix
namespace: @"http://www.w3.org/2000/xmlns/"
stringValue: namespace];
}
- (OFString*)defaultNamespace
{
OF_GETTER(_defaultNamespace, YES)
}
- (void)setDefaultNamespace: (OFString*)defaultNamespace
{
OF_SETTER(_defaultNamespace, defaultNamespace, YES, 1)
}
- (void)addChild: (OFXMLNode*)child
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (_children == nil)
_children = [[OFMutableArray alloc] init];
[_children addObject: child];
}
- (void)insertChild: (OFXMLNode*)child
atIndex: (size_t)index
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
if (_children == nil)
_children = [[OFMutableArray alloc] init];
[_children insertObject: child
atIndex: index];
}
- (void)insertChildren: (OFArray*)children
atIndex: (size_t)index
{
void *pool = objc_autoreleasePoolPush();
OFEnumerator *enumerator = [children objectEnumerator];
OFXMLNode *node;
while ((node = [enumerator nextObject]) != nil)
if ([node isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[_children insertObjectsFromArray: children
atIndex: index];
objc_autoreleasePoolPop(pool);
}
- (void)removeChild: (OFXMLNode*)child
{
if ([child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[_children removeObject: child];
}
- (void)removeChildAtIndex: (size_t)index
{
[_children removeObjectAtIndex: index];
}
- (void)replaceChild: (OFXMLNode*)child
withNode: (OFXMLNode*)node
{
if ([node isKindOfClass: [OFXMLAttribute class]] ||
[child isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[_children replaceObject: child
withObject: node];
}
- (void)replaceChildAtIndex: (size_t)index
withNode: (OFXMLNode*)node
{
if ([node isKindOfClass: [OFXMLAttribute class]])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
[_children replaceObjectAtIndex: index
withObject: node];
}
- (OFXMLElement*)elementForName: (OFString*)elementName
{
return [[self elementsForName: elementName] firstObject];
}
- (OFXMLElement*)elementForName: (OFString*)elementName
namespace: (OFString*)elementNS
{
return [[self elementsForName: elementName
namespace: elementNS] firstObject];
}
- (OFArray*)elements
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [_children objects];
size_t i, count = [_children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForName: (OFString*)elementName
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [_children objects];
size_t i, count = [_children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
objects[i]->_namespace == nil &&
[objects[i]->_name isEqual: elementName])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForNamespace: (OFString*)elementNS
{
OFMutableArray *ret = [OFMutableArray array];
OFXMLElement **objects = [_children objects];
size_t i, count = [_children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
objects[i]->_name != nil &&
[objects[i]->_namespace isEqual: elementNS])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (OFArray*)elementsForName: (OFString*)elementName
namespace: (OFString*)elementNS
{
OFMutableArray *ret;
OFXMLElement **objects;
size_t i, count;
if (elementNS == nil)
return [self elementsForName: elementName];
ret = [OFMutableArray array];
objects = [_children objects];
count = [_children count];
for (i = 0; i < count; i++)
if ([objects[i] isKindOfClass: [OFXMLElement class]] &&
[objects[i]->_namespace isEqual: elementNS] &&
[objects[i]->_name isEqual: elementName])
[ret addObject: objects[i]];
[ret makeImmutable];
return ret;
}
- (BOOL)isEqual: (id)object
{
OFXMLElement *element;
if (![object isKindOfClass: [OFXMLElement class]])
return NO;
element = object;
if (element->_name != _name && ![element->_name isEqual: _name])
return NO;
if (element->_namespace != _namespace &&
![element->_namespace isEqual: _namespace])
return NO;
if (element->_defaultNamespace != _defaultNamespace &&
![element->_defaultNamespace isEqual: _defaultNamespace])
return NO;
if (element->_attributes != _attributes &&
![element->_attributes isEqual: _attributes])
return NO;
if (element->_namespaces != _namespaces &&
![element->_namespaces isEqual: _namespaces])
return NO;
if (element->_children != _children &&
![element->_children isEqual: _children])
return NO;
return YES;
}
- (uint32_t)hash
{
uint32_t hash;
OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_name hash]);
OF_HASH_ADD_HASH(hash, [_namespace hash]);
OF_HASH_ADD_HASH(hash, [_defaultNamespace hash]);
OF_HASH_ADD_HASH(hash, [_attributes hash]);
OF_HASH_ADD_HASH(hash, [_namespaces hash]);
OF_HASH_ADD_HASH(hash, [_children hash]);
OF_HASH_FINALIZE(hash);
return hash;
}
- copy
{
return [[[self class] alloc] initWithElement: self];
}
@end
|
Modified src/OFXMLElementBuilder.h
from [25d77e9e49]
to [2639811347].
︙ | | | ︙ | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
*
* If this method is not implemented in the delegate, the default is to throw
* an OFMalformedXMLException.
*
* @param builder The builder which did not expect the close tag
* @param name The name of the close tag
* @param prefix The prefix of the close tag
* @param ns The namespace of the close tag
*/
- (void)elementBuilder: (OFXMLElementBuilder*)builder
didNotExpectCloseTag: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)ns;
/*!
* @brief This callback is called when the XML parser for the element builder
* found an unknown entity.
*
* @param builder The element builder which found an unknown entity
* @param entity The name of the entity
|
|
|
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
*
* If this method is not implemented in the delegate, the default is to throw
* an OFMalformedXMLException.
*
* @param builder The builder which did not expect the close tag
* @param name The name of the close tag
* @param prefix The prefix of the close tag
* @param namespace The namespace of the close tag
*/
- (void)elementBuilder: (OFXMLElementBuilder*)builder
didNotExpectCloseTag: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)namespace;
/*!
* @brief This callback is called when the XML parser for the element builder
* found an unknown entity.
*
* @param builder The element builder which found an unknown entity
* @param entity The name of the entity
|
︙ | | | ︙ | |
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
*
* It can also be used to build OFXMLElements from parts of the document by
* first parsing stuff using the OFXMLParser with another delegate and then
* setting the OFXMLElementBuilder as delegate for the parser.
*/
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
OFMutableArray *stack;
id <OFXMLElementBuilderDelegate> delegate;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLElementBuilderDelegate> delegate;
#endif
/*!
|
|
|
|
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
*
* It can also be used to build OFXMLElements from parts of the document by
* first parsing stuff using the OFXMLParser with another delegate and then
* setting the OFXMLElementBuilder as delegate for the parser.
*/
@interface OFXMLElementBuilder: OFObject <OFXMLParserDelegate>
{
OFMutableArray *_stack;
id <OFXMLElementBuilderDelegate> _delegate;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLElementBuilderDelegate> delegate;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/OFXMLElementBuilder.m
from [eab873b1b6]
to [13da6c9002].
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
}
- init
{
self = [super init];
@try {
stack = [[OFMutableArray alloc] init];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[stack release];
[super dealloc];
}
- (id <OFXMLElementBuilderDelegate>)delegate
{
return delegate;
}
- (void)setDelegate: (id <OFXMLElementBuilderDelegate>)delegate_
{
delegate = delegate_;
}
- (void)parser: (OFXMLParser*)parser
foundProcessingInstructions: (OFString*)pi
{
OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions
processingInstructionsWithString: pi];
OFXMLElement *parent = [stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
didStartElement: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)ns
attributes: (OFArray*)attributes
{
OFXMLElement *element;
OFXMLAttribute **objects;
size_t i, count;
element = [OFXMLElement elementWithName: name
namespace: ns];
objects = [attributes objects];
count = [attributes count];
for (i = 0; i < count; i++) {
if ([objects[i] namespace] == nil &&
[[objects[i] name] isEqual: @"xmlns"])
continue;
if ([[objects[i] namespace]
isEqual: @"http://www.w3.org/2000/xmlns/"])
[element setPrefix: [objects[i] name]
forNamespace: [objects[i] stringValue]];
[element addAttribute: objects[i]];
}
[[stack lastObject] addChild: element];
[stack addObject: element];
}
- (void)parser: (OFXMLParser*)parser
didEndElement: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)ns
{
switch ([stack count]) {
case 0:
if ([delegate respondsToSelector: @selector(elementBuilder:
didNotExpectCloseTag:prefix:namespace:)])
[delegate elementBuilder: self
didNotExpectCloseTag: name
prefix: prefix
namespace: ns];
else
@throw [OFMalformedXMLException
exceptionWithClass: [self class]];
return;
case 1:
[delegate elementBuilder: self
didBuildElement: [stack firstObject]];
break;
}
[stack removeLastObject];
}
- (void)parser: (OFXMLParser*)parser
foundCharacters: (OFString*)characters
{
OFXMLCharacters *node;
OFXMLElement *parent;
node = [OFXMLCharacters charactersWithString: characters];
parent = [stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
foundCDATA: (OFString*)CDATA
{
OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA];
OFXMLElement *parent = [stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
foundComment: (OFString*)comment
{
OFXMLComment *node = [OFXMLComment commentWithString: comment];
OFXMLElement *parent = [stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (OFString*)parser: (OFXMLParser*)parser
foundUnknownEntityNamed: (OFString*)entity
{
if ([delegate respondsToSelector:
@selector(elementBuilder:foundUnknownEntityNamed:)])
return [delegate elementBuilder: self
foundUnknownEntityNamed: entity];
return nil;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
}
- init
{
self = [super init];
@try {
_stack = [[OFMutableArray alloc] init];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_stack release];
[super dealloc];
}
- (id <OFXMLElementBuilderDelegate>)delegate
{
return _delegate;
}
- (void)setDelegate: (id <OFXMLElementBuilderDelegate>)delegate
{
_delegate = delegate;
}
- (void)parser: (OFXMLParser*)parser
foundProcessingInstructions: (OFString*)pi
{
OFXMLProcessingInstructions *node = [OFXMLProcessingInstructions
processingInstructionsWithString: pi];
OFXMLElement *parent = [_stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([_delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[_delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
didStartElement: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)namespace
attributes: (OFArray*)attributes
{
OFXMLElement *element;
OFXMLAttribute **objects;
size_t i, count;
element = [OFXMLElement elementWithName: name
namespace: namespace];
objects = [attributes objects];
count = [attributes count];
for (i = 0; i < count; i++) {
if ([objects[i] namespace] == nil &&
[[objects[i] name] isEqual: @"xmlns"])
continue;
if ([[objects[i] namespace]
isEqual: @"http://www.w3.org/2000/xmlns/"])
[element setPrefix: [objects[i] name]
forNamespace: [objects[i] stringValue]];
[element addAttribute: objects[i]];
}
[[_stack lastObject] addChild: element];
[_stack addObject: element];
}
- (void)parser: (OFXMLParser*)parser
didEndElement: (OFString*)name
prefix: (OFString*)prefix
namespace: (OFString*)namespace
{
switch ([_stack count]) {
case 0:
if ([_delegate respondsToSelector: @selector(elementBuilder:
didNotExpectCloseTag:prefix:namespace:)])
[_delegate elementBuilder: self
didNotExpectCloseTag: name
prefix: prefix
namespace: namespace];
else
@throw [OFMalformedXMLException
exceptionWithClass: [self class]];
return;
case 1:
[_delegate elementBuilder: self
didBuildElement: [_stack firstObject]];
break;
}
[_stack removeLastObject];
}
- (void)parser: (OFXMLParser*)parser
foundCharacters: (OFString*)characters
{
OFXMLCharacters *node;
OFXMLElement *parent;
node = [OFXMLCharacters charactersWithString: characters];
parent = [_stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([_delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[_delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
foundCDATA: (OFString*)CDATA
{
OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA];
OFXMLElement *parent = [_stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([_delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[_delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (void)parser: (OFXMLParser*)parser
foundComment: (OFString*)comment
{
OFXMLComment *node = [OFXMLComment commentWithString: comment];
OFXMLElement *parent = [_stack lastObject];
if (parent != nil)
[parent addChild: node];
else if ([_delegate respondsToSelector:
@selector(elementBuilder:didBuildParentlessNode:)])
[_delegate elementBuilder: self
didBuildParentlessNode: node];
}
- (OFString*)parser: (OFXMLParser*)parser
foundUnknownEntityNamed: (OFString*)entity
{
if ([_delegate respondsToSelector:
@selector(elementBuilder:foundUnknownEntityNamed:)])
return [_delegate elementBuilder: self
foundUnknownEntityNamed: entity];
return nil;
}
@end
|
Modified src/OFXMLParser.h
from [e7c5a2a327]
to [3c72bea853].
︙ | | | ︙ | |
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
* @brief An event-based XML parser.
*
* OFXMLParser is an event-based XML parser which calls the delegate's callbacks
* as soon asit finds something, thus suitable for streams as well.
*/
@interface OFXMLParser: OFObject <OFStringXMLUnescapingDelegate>
{
id <OFXMLParserDelegate> delegate;
enum {
OF_XMLPARSER_OUTSIDE_TAG,
OF_XMLPARSER_TAG_OPENED,
OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS,
OF_XMLPARSER_IN_TAG_NAME,
OF_XMLPARSER_IN_CLOSE_TAG_NAME,
OF_XMLPARSER_IN_TAG,
|
|
|
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
* @brief An event-based XML parser.
*
* OFXMLParser is an event-based XML parser which calls the delegate's callbacks
* as soon asit finds something, thus suitable for streams as well.
*/
@interface OFXMLParser: OFObject <OFStringXMLUnescapingDelegate>
{
id <OFXMLParserDelegate> _delegate;
enum {
OF_XMLPARSER_OUTSIDE_TAG,
OF_XMLPARSER_TAG_OPENED,
OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS,
OF_XMLPARSER_IN_TAG_NAME,
OF_XMLPARSER_IN_CLOSE_TAG_NAME,
OF_XMLPARSER_IN_TAG,
|
︙ | | | ︙ | |
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
OF_XMLPARSER_IN_CDATA_1,
OF_XMLPARSER_IN_CDATA_2,
OF_XMLPARSER_IN_COMMENT_OPENING,
OF_XMLPARSER_IN_COMMENT_1,
OF_XMLPARSER_IN_COMMENT_2,
OF_XMLPARSER_IN_DOCTYPE,
OF_XMLPARSER_NUM_STATES
} state;
OFDataArray *cache;
OFString *name;
OFString *prefix;
OFMutableArray *namespaces;
OFMutableArray *attributes;
OFString *attributeName;
OFString *attributePrefix;
char delimiter;
OFMutableArray *previous;
size_t level;
BOOL acceptProlog;
size_t lineNumber;
BOOL lastCarriageReturn;
BOOL finishedParsing;
of_string_encoding_t encoding;
size_t depthLimit;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLParserDelegate> delegate;
@property size_t depthLimit;
#endif
|
|
|
|
<
|
<
|
<
|
|
|
|
|
|
<
|
|
|
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
OF_XMLPARSER_IN_CDATA_1,
OF_XMLPARSER_IN_CDATA_2,
OF_XMLPARSER_IN_COMMENT_OPENING,
OF_XMLPARSER_IN_COMMENT_1,
OF_XMLPARSER_IN_COMMENT_2,
OF_XMLPARSER_IN_DOCTYPE,
OF_XMLPARSER_NUM_STATES
} _state;
OFDataArray *_cache;
OFString *_name, *_prefix;
OFMutableArray *_namespaces, *_attributes;
OFString *_attributeName, *_attributePrefix;
char _delimiter;
OFMutableArray *_previous;
size_t _level;
BOOL _acceptProlog;
size_t _lineNumber;
BOOL _lastCarriageReturn, _finishedParsing;
of_string_encoding_t _encoding;
size_t _depthLimit;
}
#ifdef OF_HAVE_PROPERTIES
@property (assign) id <OFXMLParserDelegate> delegate;
@property size_t depthLimit;
#endif
|
︙ | | | ︙ | |
Modified src/OFXMLParser.m
from [b0c5452c32]
to [ca4fab60df].
︙ | | | ︙ | |
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
}
static OF_INLINE void
resolve_attribute_namespace(OFXMLAttribute *attribute, OFArray *namespaces,
OFXMLParser *self)
{
OFString *attributeNS;
OFString *attributePrefix = attribute->ns;
if (attributePrefix == nil)
return;
attributeNS = namespace_for_prefix(attributePrefix, namespaces);
if ((attributePrefix != nil && attributeNS == nil))
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: attributePrefix];
[attribute->ns release];
attribute->ns = [attributeNS retain];
}
@implementation OFXMLParser
+ (void)initialize
{
size_t i;
|
|
|
|
|
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
}
static OF_INLINE void
resolve_attribute_namespace(OFXMLAttribute *attribute, OFArray *namespaces,
OFXMLParser *self)
{
OFString *attributeNS;
OFString *attributePrefix = attribute->_namespace;
if (attributePrefix == nil)
return;
attributeNS = namespace_for_prefix(attributePrefix, namespaces);
if ((attributePrefix != nil && attributeNS == nil))
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: attributePrefix];
[attribute->_namespace release];
attribute->_namespace = [attributeNS retain];
}
@implementation OFXMLParser
+ (void)initialize
{
size_t i;
|
︙ | | | ︙ | |
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
{
self = [super init];
@try {
void *pool;
OFMutableDictionary *dict;
cache = [[OFBigDataArray alloc] init];
previous = [[OFMutableArray alloc] init];
namespaces = [[OFMutableArray alloc] init];
attributes = [[OFMutableArray alloc] init];
pool = objc_autoreleasePoolPush();
dict = [OFMutableDictionary dictionaryWithKeysAndObjects:
@"xml", @"http://www.w3.org/XML/1998/namespace",
@"xmlns", @"http://www.w3.org/2000/xmlns/", nil];
[namespaces addObject: dict];
acceptProlog = YES;
lineNumber = 1;
encoding = OF_STRING_ENCODING_UTF_8;
depthLimit = 32;
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[cache release];
[name release];
[prefix release];
[namespaces release];
[attributes release];
[attributeName release];
[attributePrefix release];
[previous release];
[super dealloc];
}
- (id <OFXMLParserDelegate>)delegate
{
return delegate;
}
- (void)setDelegate: (id <OFXMLParserDelegate>)delegate_
{
delegate = delegate_;
}
- (size_t)depthLimit
{
return depthLimit;
}
- (void)setDepthLimit: (size_t)depthLimit_
{
depthLimit = depthLimit_;
}
- (void)parseBuffer: (const char*)buffer
length: (size_t)length
{
size_t i, last = 0;
for (i = 0; i < length; i++) {
size_t j = i;
lookupTable[state](self, selectors[state], buffer, &i, &last);
/* Ensure we don't count this character twice */
if (i != j)
continue;
if (buffer[i] == '\r' || (buffer[i] == '\n' &&
!lastCarriageReturn))
lineNumber++;
lastCarriageReturn = (buffer[i] == '\r');
}
/* In OF_XMLPARSER_IN_TAG, there can be only spaces */
if (length - last > 0 && state != OF_XMLPARSER_IN_TAG)
cache_append(cache, buffer + last, encoding, length - last);
}
- (void)parseString: (OFString*)string
{
[self parseBuffer: [string UTF8String]
length: [string UTF8StringLength]];
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
{
self = [super init];
@try {
void *pool;
OFMutableDictionary *dict;
_cache = [[OFBigDataArray alloc] init];
_previous = [[OFMutableArray alloc] init];
_namespaces = [[OFMutableArray alloc] init];
_attributes = [[OFMutableArray alloc] init];
pool = objc_autoreleasePoolPush();
dict = [OFMutableDictionary dictionaryWithKeysAndObjects:
@"xml", @"http://www.w3.org/XML/1998/namespace",
@"xmlns", @"http://www.w3.org/2000/xmlns/", nil];
[_namespaces addObject: dict];
_acceptProlog = YES;
_lineNumber = 1;
_encoding = OF_STRING_ENCODING_UTF_8;
_depthLimit = 32;
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_cache release];
[_name release];
[_prefix release];
[_namespaces release];
[_attributes release];
[_attributeName release];
[_attributePrefix release];
[_previous release];
[super dealloc];
}
- (id <OFXMLParserDelegate>)delegate
{
return _delegate;
}
- (void)setDelegate: (id <OFXMLParserDelegate>)delegate
{
_delegate = delegate;
}
- (size_t)depthLimit
{
return _depthLimit;
}
- (void)setDepthLimit: (size_t)depthLimit
{
_depthLimit = depthLimit;
}
- (void)parseBuffer: (const char*)buffer
length: (size_t)length
{
size_t i, last = 0;
for (i = 0; i < length; i++) {
size_t j = i;
lookupTable[_state](self, selectors[_state], buffer, &i, &last);
/* Ensure we don't count this character twice */
if (i != j)
continue;
if (buffer[i] == '\r' || (buffer[i] == '\n' &&
!_lastCarriageReturn))
_lineNumber++;
_lastCarriageReturn = (buffer[i] == '\r');
}
/* In OF_XMLPARSER_IN_TAG, there can be only spaces */
if (length - last > 0 && _state != OF_XMLPARSER_IN_TAG)
cache_append(_cache, buffer + last, _encoding, length - last);
}
- (void)parseString: (OFString*)string
{
[self parseBuffer: [string UTF8String]
length: [string UTF8StringLength]];
}
|
︙ | | | ︙ | |
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
|
/* Not in a tag */
- (void)OF_parseOutsideTagWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
size_t length;
if ((finishedParsing || [previous count] < 1) && buffer[*i] != ' ' &&
buffer[*i] != '\t' && buffer[*i] != '\n' && buffer[*i] != '\r' &&
buffer[*i] != '<')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (buffer[*i] != '<')
return;
if ((length = *i - *last) > 0)
cache_append(cache, buffer + *last, encoding, length);
if ([cache count] > 0) {
void *pool = objc_autoreleasePoolPush();
OFString *characters = transform_string(cache, 0, YES, self);
if ([delegate respondsToSelector:
@selector(parser:foundCharacters:)])
[delegate parser: self
foundCharacters: characters];
objc_autoreleasePoolPop(pool);
}
[cache removeAllItems];
*last = *i + 1;
state = OF_XMLPARSER_TAG_OPENED;
}
/* Tag was just opened */
- (void)OF_parseTagOpenedWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (finishedParsing && buffer[*i] != '!' && buffer[*i] != '?')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
switch (buffer[*i]) {
case '?':
*last = *i + 1;
state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
level = 0;
break;
case '/':
*last = *i + 1;
state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
acceptProlog = NO;
break;
case '!':
*last = *i + 1;
state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
acceptProlog = NO;
break;
default:
if (depthLimit > 0 && [previous count] >= depthLimit)
@throw [OFMalformedXMLException
exceptionWithClass: [self class]
parser: self];
state = OF_XMLPARSER_IN_TAG_NAME;
acceptProlog = NO;
(*i)--;
break;
}
}
/* <?xml […]?> */
- (BOOL)OF_parseXMLProcessingInstructions: (OFString*)pi
{
const char *cString;
size_t i, last, length;
int piState = 0;
OFString *attribute = nil;
OFMutableString *value = nil;
char piDelimiter = 0;
if (!acceptProlog)
return NO;
acceptProlog = NO;
pi = [pi substringWithRange: of_range(3, [pi length] - 3)];
pi = [pi stringByDeletingEnclosingWhitespaces];
cString = [pi UTF8String];
length = [pi UTF8StringLength];
for (i = last = 0; i < length; i++) {
switch (piState) {
case 0:
if (cString[i] == ' ' || cString[i] == '\t' ||
cString[i] == '\r' || cString[i] == '\n')
continue;
last = i;
piState = 1;
i--;
break;
case 1:
if (cString[i] != '=')
continue;
attribute = [OFString
stringWithUTF8String: cString + last
length: i - last];
last = i + 1;
piState = 2;
break;
case 2:
if (cString[i] != '\'' && cString[i] != '"')
return NO;
piDelimiter = cString[i];
last = i + 1;
piState = 3;
break;
case 3:
if (cString[i] != piDelimiter)
continue;
value = [OFMutableString
stringWithUTF8String: cString + last
length: i - last];
if ([attribute isEqual: @"version"])
if (![value hasPrefix: @"1."])
return NO;
if ([attribute isEqual: @"encoding"]) {
[value lowercase];
if ([value isEqual: @"utf-8"])
encoding = OF_STRING_ENCODING_UTF_8;
else if ([value isEqual: @"iso-8859-1"])
encoding =
OF_STRING_ENCODING_ISO_8859_1;
else if ([value isEqual: @"iso-8859-15"])
encoding =
OF_STRING_ENCODING_ISO_8859_15;
else if ([value isEqual: @"windows-1252"])
encoding =
OF_STRING_ENCODING_WINDOWS_1252;
else
return NO;
}
last = i + 1;
piState = 0;
break;
}
}
if (piState != 0)
return NO;
return YES;
}
/* Inside processing instructions */
- (void)OF_parseInProcessingInstructionsWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '?')
level = 1;
else if (level == 1 && buffer[*i] == '>') {
void *pool = objc_autoreleasePoolPush();
OFString *pi;
cache_append(cache, buffer + *last, encoding, *i - *last);
pi = transform_string(cache, 1, NO, nil);
if ([pi isEqual: @"xml"] || [pi hasPrefix: @"xml "] ||
[pi hasPrefix: @"xml\t"] || [pi hasPrefix: @"xml\r"] ||
[pi hasPrefix: @"xml\n"])
if (![self OF_parseXMLProcessingInstructions: pi])
@throw [OFMalformedXMLException
exceptionWithClass: [self class]
parser: self];
if ([delegate respondsToSelector:
@selector(parser:foundProcessingInstructions:)])
[delegate parser: self
foundProcessingInstructions: pi];
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
*last = *i + 1;
state = OF_XMLPARSER_OUTSIDE_TAG;
} else
level = 0;
}
/* Inside a tag, no name yet */
- (void)OF_parseInTagNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
const char *cacheCString, *tmp;
size_t length, cacheLength;
OFString *cacheString;
if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
buffer[*i] != '\r' && buffer[*i] != '>' && buffer[*i] != '/')
return;
if ((length = *i - *last) > 0)
cache_append(cache, buffer + *last, encoding, length);
pool = objc_autoreleasePoolPush();
cacheCString = [cache items];
cacheLength = [cache count];
cacheString = [OFString stringWithUTF8String: cacheCString
length: cacheLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
prefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
name = [cacheString copy];
prefix = nil;
}
if (buffer[*i] == '>' || buffer[*i] == '/') {
OFString *ns;
ns = namespace_for_prefix(prefix, namespaces);
if (prefix != nil && ns == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: prefix];
if ([delegate respondsToSelector: @selector(parser:
didStartElement:prefix:namespace:attributes:)])
[delegate parser: self
didStartElement: name
prefix: prefix
namespace: ns
attributes: nil];
if (buffer[*i] == '/') {
if ([delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[delegate parser: self
didEndElement: name
prefix: prefix
namespace: ns];
if ([previous count] == 0)
finishedParsing = YES;
} else
[previous addObject: cacheString];
[name release];
[prefix release];
name = prefix = nil;
state = (buffer[*i] == '/'
? OF_XMLPARSER_EXPECT_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
} else
state = OF_XMLPARSER_IN_TAG;
if (buffer[*i] != '/')
[namespaces addObject: [OFMutableDictionary dictionary]];
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
*last = *i + 1;
}
/* Inside a close tag, no name yet */
- (void)OF_parseInCloseTagNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
const char *cacheCString, *tmp;
size_t length, cacheLength;
OFString *cacheString;
OFString *ns;
if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
buffer[*i] != '\r' && buffer[*i] != '>')
return;
if ((length = *i - *last) > 0)
cache_append(cache, buffer + *last, encoding, length);
pool = objc_autoreleasePoolPush();
cacheCString = [cache items];
cacheLength = [cache count];
cacheString = [OFString stringWithUTF8String: cacheCString
length: cacheLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
prefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
name = [cacheString copy];
prefix = nil;
}
if (![[previous lastObject] isEqual: cacheString])
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
[previous removeLastObject];
[cache removeAllItems];
ns = namespace_for_prefix(prefix, namespaces);
if (prefix != nil && ns == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: prefix];
if ([delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[delegate parser: self
didEndElement: name
prefix: prefix
namespace: ns];
objc_autoreleasePoolPop(pool);
[namespaces removeLastObject];
[name release];
[prefix release];
name = prefix = nil;
*last = *i + 1;
state = (buffer[*i] == '>'
? OF_XMLPARSER_OUTSIDE_TAG
: OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE);
if ([previous count] == 0)
finishedParsing = YES;
}
/* Inside a tag, name found */
- (void)OF_parseInTagWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *ns;
OFXMLAttribute **attributesObjects;
size_t j, attributesCount;
if (buffer[*i] != '>' && buffer[*i] != '/') {
if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r') {
*last = *i;
state = OF_XMLPARSER_IN_ATTR_NAME;
(*i)--;
}
return;
}
attributesObjects = [attributes objects];
attributesCount = [attributes count];
ns = namespace_for_prefix(prefix, namespaces);
if (prefix != nil && ns == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: prefix];
for (j = 0; j < attributesCount; j++)
resolve_attribute_namespace(attributesObjects[j], namespaces,
self);
pool = objc_autoreleasePoolPush();
if ([delegate respondsToSelector:
@selector(parser:didStartElement:prefix:namespace:attributes:)])
[delegate parser: self
didStartElement: name
prefix: prefix
namespace: ns
attributes: attributes];
if (buffer[*i] == '/') {
if ([delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[delegate parser: self
didEndElement: name
prefix: prefix
namespace: ns];
if ([previous count] == 0)
finishedParsing = YES;
[namespaces removeLastObject];
} else if (prefix != nil) {
OFString *str = [OFString stringWithFormat: @"%@:%@",
prefix, name];
[previous addObject: str];
} else
[previous addObject: name];
objc_autoreleasePoolPop(pool);
[name release];
[prefix release];
[attributes removeAllObjects];
name = prefix = nil;
*last = *i + 1;
state = (buffer[*i] == '/'
? OF_XMLPARSER_EXPECT_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
}
/* Looking for attribute name */
- (void)OF_parseInAttributeNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFMutableString *cacheString;
const char *cacheCString, *tmp;
size_t length, cacheLength;
if (buffer[*i] != '=')
return;
if ((length = *i - *last) > 0)
cache_append(cache, buffer + *last, encoding, length);
pool = objc_autoreleasePoolPush();
cacheString = [OFMutableString stringWithUTF8String: [cache items]
length: [cache count]];
[cacheString deleteEnclosingWhitespaces];
/* Prevent a useless copy later */
[cacheString makeImmutable];
cacheCString = [cacheString UTF8String];
cacheLength = [cacheString UTF8StringLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
attributeName = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
attributePrefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
attributeName = [cacheString copy];
attributePrefix = nil;
}
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
*last = *i + 1;
state = OF_XMLPARSER_EXPECT_DELIM;
}
/* Expecting delimiter */
- (void)OF_parseExpectDelimiterWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
*last = *i + 1;
if (buffer[*i] == ' ' || buffer[*i] == '\t' || buffer[*i] == '\n' ||
buffer[*i] == '\r')
return;
if (buffer[*i] != '\'' && buffer[*i] != '"')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
delimiter = buffer[*i];
state = OF_XMLPARSER_IN_ATTR_VALUE;
}
/* Looking for attribute value */
- (void)OF_parseInAttributeValueWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *attributeValue;
size_t length;
if (buffer[*i] != delimiter)
return;
if ((length = *i - *last) > 0)
cache_append(cache, buffer + *last, encoding, length);
pool = objc_autoreleasePoolPush();
attributeValue = transform_string(cache, 0, YES, self);
if (attributePrefix == nil && [attributeName isEqual: @"xmlns"])
[[namespaces lastObject] setObject: attributeValue
forKey: @""];
if ([attributePrefix isEqual: @"xmlns"])
[[namespaces lastObject] setObject: attributeValue
forKey: attributeName];
[attributes addObject:
[OFXMLAttribute attributeWithName: attributeName
namespace: attributePrefix
stringValue: attributeValue]];
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
[attributeName release];
[attributePrefix release];
attributeName = attributePrefix = nil;
*last = *i + 1;
state = OF_XMLPARSER_IN_TAG;
}
/* Expecting closing '>' */
- (void)OF_parseExpectCloseWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '>') {
*last = *i + 1;
state = OF_XMLPARSER_OUTSIDE_TAG;
} else
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
}
/* Expecting closing '>' or space */
- (void)OF_parseExpectSpaceOrCloseWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '>') {
*last = *i + 1;
state = OF_XMLPARSER_OUTSIDE_TAG;
} else if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
}
/* In <! */
- (void)OF_parseInExclamationMarkWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (finishedParsing && buffer[*i] != '-')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (buffer[*i] == '-')
state = OF_XMLPARSER_IN_COMMENT_OPENING;
else if (buffer[*i] == '[') {
state = OF_XMLPARSER_IN_CDATA_OPENING;
level = 0;
} else if (buffer[*i] == 'D') {
state = OF_XMLPARSER_IN_DOCTYPE;
level = 0;
} else
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
*last = *i + 1;
}
/* CDATA */
- (void)OF_parseInCDATAOpeningWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] != "CDATA["[level])
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (++level == 6) {
state = OF_XMLPARSER_IN_CDATA_1;
level = 0;
}
*last = *i + 1;
}
- (void)OF_parseInCDATA1WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == ']')
level++;
else
level = 0;
if (level == 2)
state = OF_XMLPARSER_IN_CDATA_2;
}
- (void)OF_parseInCDATA2WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *CDATA;
if (buffer[*i] != '>') {
state = OF_XMLPARSER_IN_CDATA_1;
level = (buffer[*i] == ']' ? 1 : 0);
return;
}
pool = objc_autoreleasePoolPush();
cache_append(cache, buffer + *last, encoding, *i - *last);
CDATA = transform_string(cache, 2, NO, nil);
if ([delegate respondsToSelector: @selector(parser:foundCDATA:)])
[delegate parser: self
foundCDATA: CDATA];
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
*last = *i + 1;
state = OF_XMLPARSER_OUTSIDE_TAG;
}
/* Comment */
- (void)OF_parseInCommentOpeningWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] != '-')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
*last = *i + 1;
state = OF_XMLPARSER_IN_COMMENT_1;
level = 0;
}
- (void)OF_parseInComment1WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '-')
level++;
else
level = 0;
if (level == 2)
state = OF_XMLPARSER_IN_COMMENT_2;
}
- (void)OF_parseInComment2WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *comment;
if (buffer[*i] != '>')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
pool = objc_autoreleasePoolPush();
cache_append(cache, buffer + *last, encoding, *i - *last);
comment = transform_string(cache, 2, NO, nil);
if ([delegate respondsToSelector: @selector(parser:foundComment:)])
[delegate parser: self
foundComment: comment];
objc_autoreleasePoolPop(pool);
[cache removeAllItems];
*last = *i + 1;
state = OF_XMLPARSER_OUTSIDE_TAG;
}
/* In <!DOCTYPE ...> */
- (void)OF_parseInDoctypeWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if ((level < 6 && buffer[*i] != "OCTYPE"[level]) ||
(level == 6 && buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r'))
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (level < 7 || buffer[*i] == '<')
level++;
if (buffer[*i] == '>') {
if (level == 7)
state = OF_XMLPARSER_OUTSIDE_TAG;
else
level--;
}
*last = *i + 1;
}
- (size_t)lineNumber
{
return lineNumber;
}
- (BOOL)finishedParsing
{
return finishedParsing;
}
- (OFString*)string: (OFString*)string
containsUnknownEntityNamed: (OFString*)entity
{
if ([delegate respondsToSelector:
@selector(parser:foundUnknownEntityNamed:)])
return [delegate parser: self
foundUnknownEntityNamed: entity];
return nil;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
|
/* Not in a tag */
- (void)OF_parseOutsideTagWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
size_t length;
if ((_finishedParsing || [_previous count] < 1) && buffer[*i] != ' ' &&
buffer[*i] != '\t' && buffer[*i] != '\n' && buffer[*i] != '\r' &&
buffer[*i] != '<')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (buffer[*i] != '<')
return;
if ((length = *i - *last) > 0)
cache_append(_cache, buffer + *last, _encoding, length);
if ([_cache count] > 0) {
void *pool = objc_autoreleasePoolPush();
OFString *characters = transform_string(_cache, 0, YES, self);
if ([_delegate respondsToSelector:
@selector(parser:foundCharacters:)])
[_delegate parser: self
foundCharacters: characters];
objc_autoreleasePoolPop(pool);
}
[_cache removeAllItems];
*last = *i + 1;
_state = OF_XMLPARSER_TAG_OPENED;
}
/* Tag was just opened */
- (void)OF_parseTagOpenedWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (_finishedParsing && buffer[*i] != '!' && buffer[*i] != '?')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
switch (buffer[*i]) {
case '?':
*last = *i + 1;
_state = OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS;
_level = 0;
break;
case '/':
*last = *i + 1;
_state = OF_XMLPARSER_IN_CLOSE_TAG_NAME;
_acceptProlog = NO;
break;
case '!':
*last = *i + 1;
_state = OF_XMLPARSER_IN_EXCLAMATIONMARK;
_acceptProlog = NO;
break;
default:
if (_depthLimit > 0 && [_previous count] >= _depthLimit)
@throw [OFMalformedXMLException
exceptionWithClass: [self class]
parser: self];
_state = OF_XMLPARSER_IN_TAG_NAME;
_acceptProlog = NO;
(*i)--;
break;
}
}
/* <?xml […]?> */
- (BOOL)OF_parseXMLProcessingInstructions: (OFString*)pi
{
const char *cString;
size_t i, last, length;
int PIState = 0;
OFString *attribute = nil;
OFMutableString *value = nil;
char piDelimiter = 0;
if (!_acceptProlog)
return NO;
_acceptProlog = NO;
pi = [pi substringWithRange: of_range(3, [pi length] - 3)];
pi = [pi stringByDeletingEnclosingWhitespaces];
cString = [pi UTF8String];
length = [pi UTF8StringLength];
for (i = last = 0; i < length; i++) {
switch (PIState) {
case 0:
if (cString[i] == ' ' || cString[i] == '\t' ||
cString[i] == '\r' || cString[i] == '\n')
continue;
last = i;
PIState = 1;
i--;
break;
case 1:
if (cString[i] != '=')
continue;
attribute = [OFString
stringWithUTF8String: cString + last
length: i - last];
last = i + 1;
PIState = 2;
break;
case 2:
if (cString[i] != '\'' && cString[i] != '"')
return NO;
piDelimiter = cString[i];
last = i + 1;
PIState = 3;
break;
case 3:
if (cString[i] != piDelimiter)
continue;
value = [OFMutableString
stringWithUTF8String: cString + last
length: i - last];
if ([attribute isEqual: @"version"])
if (![value hasPrefix: @"1."])
return NO;
if ([attribute isEqual: @"encoding"]) {
[value lowercase];
if ([value isEqual: @"utf-8"])
_encoding = OF_STRING_ENCODING_UTF_8;
else if ([value isEqual: @"iso-8859-1"])
_encoding =
OF_STRING_ENCODING_ISO_8859_1;
else if ([value isEqual: @"iso-8859-15"])
_encoding =
OF_STRING_ENCODING_ISO_8859_15;
else if ([value isEqual: @"windows-1252"])
_encoding =
OF_STRING_ENCODING_WINDOWS_1252;
else
return NO;
}
last = i + 1;
PIState = 0;
break;
}
}
if (PIState != 0)
return NO;
return YES;
}
/* Inside processing instructions */
- (void)OF_parseInProcessingInstructionsWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '?')
_level = 1;
else if (_level == 1 && buffer[*i] == '>') {
void *pool = objc_autoreleasePoolPush();
OFString *PI;
cache_append(_cache, buffer + *last, _encoding, *i - *last);
PI = transform_string(_cache, 1, NO, nil);
if ([PI isEqual: @"xml"] || [PI hasPrefix: @"xml "] ||
[PI hasPrefix: @"xml\t"] || [PI hasPrefix: @"xml\r"] ||
[PI hasPrefix: @"xml\n"])
if (![self OF_parseXMLProcessingInstructions: PI])
@throw [OFMalformedXMLException
exceptionWithClass: [self class]
parser: self];
if ([_delegate respondsToSelector:
@selector(parser:foundProcessingInstructions:)])
[_delegate parser: self
foundProcessingInstructions: PI];
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
*last = *i + 1;
_state = OF_XMLPARSER_OUTSIDE_TAG;
} else
_level = 0;
}
/* Inside a tag, no name yet */
- (void)OF_parseInTagNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
const char *cacheCString, *tmp;
size_t length, cacheLength;
OFString *cacheString;
if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
buffer[*i] != '\r' && buffer[*i] != '>' && buffer[*i] != '/')
return;
if ((length = *i - *last) > 0)
cache_append(_cache, buffer + *last, _encoding, length);
pool = objc_autoreleasePoolPush();
cacheCString = [_cache items];
cacheLength = [_cache count];
cacheString = [OFString stringWithUTF8String: cacheCString
length: cacheLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
_name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
_prefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
_name = [cacheString copy];
_prefix = nil;
}
if (buffer[*i] == '>' || buffer[*i] == '/') {
OFString *namespace;
namespace = namespace_for_prefix(_prefix, _namespaces);
if (_prefix != nil && namespace == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: _prefix];
if ([_delegate respondsToSelector: @selector(parser:
didStartElement:prefix:namespace:attributes:)])
[_delegate parser: self
didStartElement: _name
prefix: _prefix
namespace: namespace
attributes: nil];
if (buffer[*i] == '/') {
if ([_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[_delegate parser: self
didEndElement: _name
prefix: _prefix
namespace: namespace];
if ([_previous count] == 0)
_finishedParsing = YES;
} else
[_previous addObject: cacheString];
[_name release];
[_prefix release];
_name = _prefix = nil;
_state = (buffer[*i] == '/'
? OF_XMLPARSER_EXPECT_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
} else
_state = OF_XMLPARSER_IN_TAG;
if (buffer[*i] != '/')
[_namespaces addObject: [OFMutableDictionary dictionary]];
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
*last = *i + 1;
}
/* Inside a close tag, no name yet */
- (void)OF_parseInCloseTagNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
const char *cacheCString, *tmp;
size_t length, cacheLength;
OFString *cacheString, *namespace;
if (buffer[*i] != ' ' && buffer[*i] != '\t' && buffer[*i] != '\n' &&
buffer[*i] != '\r' && buffer[*i] != '>')
return;
if ((length = *i - *last) > 0)
cache_append(_cache, buffer + *last, _encoding, length);
pool = objc_autoreleasePoolPush();
cacheCString = [_cache items];
cacheLength = [_cache count];
cacheString = [OFString stringWithUTF8String: cacheCString
length: cacheLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
_name = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
_prefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
_name = [cacheString copy];
_prefix = nil;
}
if (![[_previous lastObject] isEqual: cacheString])
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
[_previous removeLastObject];
[_cache removeAllItems];
namespace = namespace_for_prefix(_prefix, _namespaces);
if (_prefix != nil && namespace == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: _prefix];
if ([_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[_delegate parser: self
didEndElement: _name
prefix: _prefix
namespace: namespace];
objc_autoreleasePoolPop(pool);
[_namespaces removeLastObject];
[_name release];
[_prefix release];
_name = _prefix = nil;
*last = *i + 1;
_state = (buffer[*i] == '>'
? OF_XMLPARSER_OUTSIDE_TAG
: OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE);
if ([_previous count] == 0)
_finishedParsing = YES;
}
/* Inside a tag, name found */
- (void)OF_parseInTagWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *namespace;
OFXMLAttribute **attributesObjects;
size_t j, attributesCount;
if (buffer[*i] != '>' && buffer[*i] != '/') {
if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r') {
*last = *i;
_state = OF_XMLPARSER_IN_ATTR_NAME;
(*i)--;
}
return;
}
attributesObjects = [_attributes objects];
attributesCount = [_attributes count];
namespace = namespace_for_prefix(_prefix, _namespaces);
if (_prefix != nil && namespace == nil)
@throw [OFUnboundNamespaceException
exceptionWithClass: [self class]
prefix: _prefix];
for (j = 0; j < attributesCount; j++)
resolve_attribute_namespace(attributesObjects[j], _namespaces,
self);
pool = objc_autoreleasePoolPush();
if ([_delegate respondsToSelector:
@selector(parser:didStartElement:prefix:namespace:attributes:)])
[_delegate parser: self
didStartElement: _name
prefix: _prefix
namespace: namespace
attributes: _attributes];
if (buffer[*i] == '/') {
if ([_delegate respondsToSelector:
@selector(parser:didEndElement:prefix:namespace:)])
[_delegate parser: self
didEndElement: _name
prefix: _prefix
namespace: namespace];
if ([_previous count] == 0)
_finishedParsing = YES;
[_namespaces removeLastObject];
} else if (_prefix != nil) {
OFString *str = [OFString stringWithFormat: @"%@:%@",
_prefix, _name];
[_previous addObject: str];
} else
[_previous addObject: _name];
objc_autoreleasePoolPop(pool);
[_name release];
[_prefix release];
[_attributes removeAllObjects];
_name = _prefix = nil;
*last = *i + 1;
_state = (buffer[*i] == '/'
? OF_XMLPARSER_EXPECT_CLOSE
: OF_XMLPARSER_OUTSIDE_TAG);
}
/* Looking for attribute name */
- (void)OF_parseInAttributeNameWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFMutableString *cacheString;
const char *cacheCString, *tmp;
size_t length, cacheLength;
if (buffer[*i] != '=')
return;
if ((length = *i - *last) > 0)
cache_append(_cache, buffer + *last, _encoding, length);
pool = objc_autoreleasePoolPush();
cacheString = [OFMutableString stringWithUTF8String: [_cache items]
length: [_cache count]];
[cacheString deleteEnclosingWhitespaces];
/* Prevent a useless copy later */
[cacheString makeImmutable];
cacheCString = [cacheString UTF8String];
cacheLength = [cacheString UTF8StringLength];
if ((tmp = memchr(cacheCString, ':', cacheLength)) != NULL) {
_attributeName = [[OFString alloc]
initWithUTF8String: tmp + 1
length: cacheLength - (tmp - cacheCString) - 1];
_attributePrefix = [[OFString alloc]
initWithUTF8String: cacheCString
length: tmp - cacheCString];
} else {
_attributeName = [cacheString copy];
_attributePrefix = nil;
}
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
*last = *i + 1;
_state = OF_XMLPARSER_EXPECT_DELIM;
}
/* Expecting delimiter */
- (void)OF_parseExpectDelimiterWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
*last = *i + 1;
if (buffer[*i] == ' ' || buffer[*i] == '\t' || buffer[*i] == '\n' ||
buffer[*i] == '\r')
return;
if (buffer[*i] != '\'' && buffer[*i] != '"')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
_delimiter = buffer[*i];
_state = OF_XMLPARSER_IN_ATTR_VALUE;
}
/* Looking for attribute value */
- (void)OF_parseInAttributeValueWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *attributeValue;
size_t length;
if (buffer[*i] != _delimiter)
return;
if ((length = *i - *last) > 0)
cache_append(_cache, buffer + *last, _encoding, length);
pool = objc_autoreleasePoolPush();
attributeValue = transform_string(_cache, 0, YES, self);
if (_attributePrefix == nil && [_attributeName isEqual: @"xmlns"])
[[_namespaces lastObject] setObject: attributeValue
forKey: @""];
if ([_attributePrefix isEqual: @"xmlns"])
[[_namespaces lastObject] setObject: attributeValue
forKey: _attributeName];
[_attributes addObject:
[OFXMLAttribute attributeWithName: _attributeName
namespace: _attributePrefix
stringValue: attributeValue]];
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
[_attributeName release];
[_attributePrefix release];
_attributeName = _attributePrefix = nil;
*last = *i + 1;
_state = OF_XMLPARSER_IN_TAG;
}
/* Expecting closing '>' */
- (void)OF_parseExpectCloseWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '>') {
*last = *i + 1;
_state = OF_XMLPARSER_OUTSIDE_TAG;
} else
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
}
/* Expecting closing '>' or space */
- (void)OF_parseExpectSpaceOrCloseWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '>') {
*last = *i + 1;
_state = OF_XMLPARSER_OUTSIDE_TAG;
} else if (buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
}
/* In <! */
- (void)OF_parseInExclamationMarkWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (_finishedParsing && buffer[*i] != '-')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (buffer[*i] == '-')
_state = OF_XMLPARSER_IN_COMMENT_OPENING;
else if (buffer[*i] == '[') {
_state = OF_XMLPARSER_IN_CDATA_OPENING;
_level = 0;
} else if (buffer[*i] == 'D') {
_state = OF_XMLPARSER_IN_DOCTYPE;
_level = 0;
} else
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
*last = *i + 1;
}
/* CDATA */
- (void)OF_parseInCDATAOpeningWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] != "CDATA["[_level])
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (++_level == 6) {
_state = OF_XMLPARSER_IN_CDATA_1;
_level = 0;
}
*last = *i + 1;
}
- (void)OF_parseInCDATA1WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == ']')
_level++;
else
_level = 0;
if (_level == 2)
_state = OF_XMLPARSER_IN_CDATA_2;
}
- (void)OF_parseInCDATA2WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *CDATA;
if (buffer[*i] != '>') {
_state = OF_XMLPARSER_IN_CDATA_1;
_level = (buffer[*i] == ']' ? 1 : 0);
return;
}
pool = objc_autoreleasePoolPush();
cache_append(_cache, buffer + *last, _encoding, *i - *last);
CDATA = transform_string(_cache, 2, NO, nil);
if ([_delegate respondsToSelector: @selector(parser:foundCDATA:)])
[_delegate parser: self
foundCDATA: CDATA];
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
*last = *i + 1;
_state = OF_XMLPARSER_OUTSIDE_TAG;
}
/* Comment */
- (void)OF_parseInCommentOpeningWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] != '-')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
*last = *i + 1;
_state = OF_XMLPARSER_IN_COMMENT_1;
_level = 0;
}
- (void)OF_parseInComment1WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if (buffer[*i] == '-')
_level++;
else
_level = 0;
if (_level == 2)
_state = OF_XMLPARSER_IN_COMMENT_2;
}
- (void)OF_parseInComment2WithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
void *pool;
OFString *comment;
if (buffer[*i] != '>')
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
pool = objc_autoreleasePoolPush();
cache_append(_cache, buffer + *last, _encoding, *i - *last);
comment = transform_string(_cache, 2, NO, nil);
if ([_delegate respondsToSelector: @selector(parser:foundComment:)])
[_delegate parser: self
foundComment: comment];
objc_autoreleasePoolPop(pool);
[_cache removeAllItems];
*last = *i + 1;
_state = OF_XMLPARSER_OUTSIDE_TAG;
}
/* In <!DOCTYPE ...> */
- (void)OF_parseInDoctypeWithBuffer: (const char*)buffer
i: (size_t*)i
last: (size_t*)last
{
if ((_level < 6 && buffer[*i] != "OCTYPE"[_level]) ||
(_level == 6 && buffer[*i] != ' ' && buffer[*i] != '\t' &&
buffer[*i] != '\n' && buffer[*i] != '\r'))
@throw [OFMalformedXMLException exceptionWithClass: [self class]
parser: self];
if (_level < 7 || buffer[*i] == '<')
_level++;
if (buffer[*i] == '>') {
if (_level == 7)
_state = OF_XMLPARSER_OUTSIDE_TAG;
else
_level--;
}
*last = *i + 1;
}
- (size_t)lineNumber
{
return _lineNumber;
}
- (BOOL)finishedParsing
{
return _finishedParsing;
}
- (OFString*)string: (OFString*)string
containsUnknownEntityNamed: (OFString*)entity
{
if ([_delegate respondsToSelector:
@selector(parser:foundUnknownEntityNamed:)])
return [_delegate parser: self
foundUnknownEntityNamed: entity];
return nil;
}
@end
|
Modified src/OFXMLProcessingInstructions.h
from [855fc8a6f5]
to [03f62c6277].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class for representing XML processing instructions.
*/
@interface OFXMLProcessingInstructions: OFXMLNode
{
OFString *processingInstructions;
}
/*!
* @brief Creates a new OFXMLProcessingInstructions with the specified string.
*
* @param string The string for the processing instructions
* @return A new OFXMLProcessingInstructions
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFXMLNode.h"
/*!
* @brief A class for representing XML processing instructions.
*/
@interface OFXMLProcessingInstructions: OFXMLNode
{
OFString *_processingInstructions;
}
/*!
* @brief Creates a new OFXMLProcessingInstructions with the specified string.
*
* @param string The string for the processing instructions
* @return A new OFXMLProcessingInstructions
|
︙ | | | ︙ | |
Modified src/OFXMLProcessingInstructions.m
from [1362f58459]
to [ba4e0fdeba].
︙ | | | ︙ | |
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
processingInstructions = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
|
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
}
- initWithString: (OFString*)string
{
self = [super init];
@try {
_processingInstructions = [string copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
|
︙ | | | ︙ | |
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
processingInstructions = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLProcessingInstructions *otherProcessingInstructions;
if (![object isKindOfClass: [OFXMLProcessingInstructions class]])
return NO;
otherProcessingInstructions = object;
return ([otherProcessingInstructions->processingInstructions
isEqual: processingInstructions]);
}
- (uint32_t)hash
{
return [processingInstructions hash];
}
- (OFString*)stringValue
{
return @"";
}
- (OFString*)XMLString
{
return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
OFString *ret;
if (indentation > 0 && level > 0) {
char *whitespaces = [self allocMemoryWithSize:
(level * indentation) + 1];
memset(whitespaces, ' ', level * indentation);
whitespaces[level * indentation] = 0;
@try {
ret = [OFString stringWithFormat:
@"%s<?%@?>",
whitespaces,
processingInstructions];
} @finally {
[self freeMemory: whitespaces];
}
} else
ret = [OFString stringWithFormat: @"<?%@?>",
processingInstructions];
return ret;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<?%@?>", processingInstructions];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: processingInstructions];
}
@end
|
|
|
|
|
|
|
|
|
<
<
|
|
|
|
|
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
if (![[element name] isEqual: [self className]] ||
![[element namespace] isEqual: OF_SERIALIZATION_NS])
@throw [OFInvalidArgumentException
exceptionWithClass: [self class]
selector: _cmd];
_processingInstructions = [[element stringValue] copy];
objc_autoreleasePoolPop(pool);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (BOOL)isEqual: (id)object
{
OFXMLProcessingInstructions *processingInstructions;
if (![object isKindOfClass: [OFXMLProcessingInstructions class]])
return NO;
processingInstructions = object;
return ([processingInstructions->_processingInstructions
isEqual: _processingInstructions]);
}
- (uint32_t)hash
{
return [_processingInstructions hash];
}
- (OFString*)stringValue
{
return @"";
}
- (OFString*)XMLString
{
return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
{
return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}
- (OFString*)XMLStringWithIndentation: (unsigned int)indentation
level: (unsigned int)level
{
OFString *ret;
if (indentation > 0 && level > 0) {
char *whitespaces = [self allocMemoryWithSize:
(level * indentation) + 1];
memset(whitespaces, ' ', level * indentation);
whitespaces[level * indentation] = 0;
@try {
ret = [OFString stringWithFormat:
@"%s<?%@?>", whitespaces, _processingInstructions];
} @finally {
[self freeMemory: whitespaces];
}
} else
ret = [OFString stringWithFormat: @"<?%@?>",
_processingInstructions];
return ret;
}
- (OFString*)description
{
return [OFString stringWithFormat: @"<?%@?>", _processingInstructions];
}
- (OFXMLElement*)XMLElementBySerializing
{
return [OFXMLElement elementWithName: [self className]
namespace: OF_SERIALIZATION_NS
stringValue: _processingInstructions];
}
@end
|
Modified src/bridge/NSArray_OFArray.h
from [64cda1af47]
to [0ab5200b4a].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
|
#import <Foundation/NSArray.h>
@class OFArray;
@interface NSArray_OFArray: NSArray
{
OFArray *array;
}
- initWithOFArray: (OFArray*)array;
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
26
27
|
#import <Foundation/NSArray.h>
@class OFArray;
@interface NSArray_OFArray: NSArray
{
OFArray *_array;
}
- initWithOFArray: (OFArray*)array;
@end
|
Modified src/bridge/NSArray_OFArray.m
from [61bec25775]
to [434089e7ff].
︙ | | | ︙ | |
17
18
19
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
|
#import "NSArray_OFArray.h"
#import "OFArray.h"
#import "OFBridging.h"
#import "OFOutOfRangeException.h"
@implementation NSArray_OFArray
- initWithOFArray: (OFArray*)array_
{
if ((self = [super init]) != nil) {
@try {
array = [array_ retain];
} @catch (id e) {
return nil;
}
}
return self;
}
- (id)objectAtIndex: (NSUInteger)index
{
id object = [array objectAtIndex: index];
if ([object conformsToProtocol: @protocol(OFBridging)])
return [object NSObject];
return object;
}
- (NSUInteger)count
{
size_t count = [array count];
if (count > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return (NSUInteger)count;
}
@end
|
|
|
|
|
|
17
18
19
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
|
#import "NSArray_OFArray.h"
#import "OFArray.h"
#import "OFBridging.h"
#import "OFOutOfRangeException.h"
@implementation NSArray_OFArray
- initWithOFArray: (OFArray*)array
{
if ((self = [super init]) != nil) {
@try {
_array = [array retain];
} @catch (id e) {
return nil;
}
}
return self;
}
- (id)objectAtIndex: (NSUInteger)index
{
id object = [_array objectAtIndex: index];
if ([object conformsToProtocol: @protocol(OFBridging)])
return [object NSObject];
return object;
}
- (NSUInteger)count
{
size_t count = [_array count];
if (count > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return (NSUInteger)count;
}
@end
|
Modified src/bridge/NSDictionary_OFDictionary.h
from [ed07628feb]
to [6e0ce58f25].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
|
#import <Foundation/NSDictionary.h>
@class OFDictionary;
@interface NSDictionary_OFDictionary: NSDictionary
{
OFDictionary *dictionary;
}
- initWithOFDictionary: (OFDictionary*)dictionary;
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
26
27
|
#import <Foundation/NSDictionary.h>
@class OFDictionary;
@interface NSDictionary_OFDictionary: NSDictionary
{
OFDictionary *_dictionary;
}
- initWithOFDictionary: (OFDictionary*)dictionary;
@end
|
Modified src/bridge/NSDictionary_OFDictionary.m
from [8b0d7ded32]
to [f733fe8d7e].
︙ | | | ︙ | |
19
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
|
#import "NSBridging.h"
#import "OFBridging.h"
#import "OFOutOfRangeException.h"
@implementation NSDictionary_OFDictionary
- initWithOFDictionary: (OFDictionary*)dictionary_
{
if ((self = [super init]) != nil) {
@try {
dictionary = [dictionary_ retain];
} @catch (id e) {
return nil;
}
}
return self;
}
- (id)objectForKey: (id)key
{
id object;
if ([key conformsToProtocol: @protocol(NSBridging)])
key = [key OFObject];
object = [dictionary objectForKey: key];
if ([object conformsToProtocol: @protocol(OFBridging)])
return [object NSObject];
return object;
}
- (NSUInteger)count
{
size_t count = [dictionary count];
if (count > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return (NSUInteger)count;
}
@end
|
|
|
|
|
|
19
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
|
#import "NSBridging.h"
#import "OFBridging.h"
#import "OFOutOfRangeException.h"
@implementation NSDictionary_OFDictionary
- initWithOFDictionary: (OFDictionary*)dictionary
{
if ((self = [super init]) != nil) {
@try {
_dictionary = [dictionary retain];
} @catch (id e) {
return nil;
}
}
return self;
}
- (id)objectForKey: (id)key
{
id object;
if ([key conformsToProtocol: @protocol(NSBridging)])
key = [key OFObject];
object = [_dictionary objectForKey: key];
if ([object conformsToProtocol: @protocol(OFBridging)])
return [object NSObject];
return object;
}
- (NSUInteger)count
{
size_t count = [_dictionary count];
if (count > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
return (NSUInteger)count;
}
@end
|
Modified src/bridge/OFArray_NSArray.h
from [7886c58cee]
to [02bad917af].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFArray.h"
@class NSArray;
@interface OFArray_NSArray: OFArray
{
NSArray *array;
}
- initWithNSArray: (NSArray*)array;
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFArray.h"
@class NSArray;
@interface OFArray_NSArray: OFArray
{
NSArray *_array;
}
- initWithNSArray: (NSArray*)array;
@end
|
Modified src/bridge/OFArray_NSArray.m
from [ed89b3631c]
to [550babc622].
︙ | | | ︙ | |
19
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
|
#import "OFArray_NSArray.h"
#import "NSBridging.h"
#import "OFInitializationFailedException.h"
#import "OFOutOfRangeException.h"
@implementation OFArray_NSArray
- initWithNSArray: (NSArray*)array_
{
self = [super init];
@try {
array = [array_ retain];
if (array == nil)
@throw [OFInitializationFailedException
exceptionWithClass: isa];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (id)objectAtIndex: (size_t)index
{
id object;
if (index > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
object = [array objectAtIndex: index];
if ([object conformsToProtocol: @protocol(NSBridging)])
return [object OFObject];
return object;
}
- (size_t)count
{
return [array count];
}
@end
|
|
<
<
|
>
>
|
|
|
19
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
|
#import "OFArray_NSArray.h"
#import "NSBridging.h"
#import "OFInitializationFailedException.h"
#import "OFOutOfRangeException.h"
@implementation OFArray_NSArray
- initWithNSArray: (NSArray*)array
{
self = [super init];
@try {
if (array == nil)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
_array = [array retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (id)objectAtIndex: (size_t)index
{
id object;
if (index > NSUIntegerMax)
@throw [OFOutOfRangeException exceptionWithClass: [self class]];
object = [_array objectAtIndex: index];
if ([object conformsToProtocol: @protocol(NSBridging)])
return [object OFObject];
return object;
}
- (size_t)count
{
return [_array count];
}
@end
|
Modified src/bridge/OFDictionary_NSDictionary.h
from [7826d59e94]
to [f68f3a5712].
︙ | | | ︙ | |
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFDictionary.h"
@class NSDictionary;
@interface OFDictionary_NSDictionary: OFDictionary
{
NSDictionary *dictionary;
}
- initWithNSDictionary: (NSDictionary*)dictionary;
@end
|
|
|
16
17
18
19
20
21
22
23
24
25
26
27
|
#import "OFDictionary.h"
@class NSDictionary;
@interface OFDictionary_NSDictionary: OFDictionary
{
NSDictionary *_dictionary;
}
- initWithNSDictionary: (NSDictionary*)dictionary;
@end
|
Modified src/bridge/OFDictionary_NSDictionary.m
from [9a66c6414d]
to [cb3b31f5ab].
︙ | | | ︙ | |
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
|
#import "NSBridging.h"
#import "OFBridging.h"
#import "OFInitializationFailedException.h"
@implementation OFDictionary_NSDictionary
- initWithNSDictionary: (NSDictionary*)dictionary_
{
self = [super init];
@try {
dictionary = [dictionary_ retain];
if (dictionary == nil)
@throw [OFInitializationFailedException
exceptionWithClass: isa];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (id)objectForKey: (id)key
{
id object;
if ([key conformsToProtocol: @protocol(OFBridging)])
key = [key NSObject];
object = [dictionary objectForKey: key];
if ([object conformsToProtocol: @protocol(NSBridging)])
return [object OFObject];
return object;
}
- (size_t)count
{
return [dictionary count];
}
@end
|
|
<
<
|
>
>
|
|
|
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
|
#import "NSBridging.h"
#import "OFBridging.h"
#import "OFInitializationFailedException.h"
@implementation OFDictionary_NSDictionary
- initWithNSDictionary: (NSDictionary*)dictionary
{
self = [super init];
@try {
if (dictionary == nil)
@throw [OFInitializationFailedException
exceptionWithClass: [self class]];
_dictionary = [dictionary retain];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (id)objectForKey: (id)key
{
id object;
if ([key conformsToProtocol: @protocol(OFBridging)])
key = [key NSObject];
object = [_dictionary objectForKey: key];
if ([object conformsToProtocol: @protocol(NSBridging)])
return [object OFObject];
return object;
}
- (size_t)count
{
return [_dictionary count];
}
@end
|
Modified src/exceptions/OFAcceptFailedException.h
from [be9ae8cbf9]
to [f828728a28].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that accepting a connection failed.
*/
@interface OFAcceptFailedException: OFException
{
OFTCPSocket *socket;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int errNo;
#endif
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that accepting a connection failed.
*/
@interface OFAcceptFailedException: OFException
{
OFTCPSocket *_socket;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFAcceptFailedException.m
from [69a04b661c]
to [13c27ee54c].
︙ | | | ︙ | |
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
|
#import "OFAcceptFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAcceptFailedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
{
return [[[self alloc] initWithClass: class_
socket: socket] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
{
self = [super initWithClass: class_];
socket = [socket_ retain];
errNo = GET_SOCK_ERRNO;
return self;
}
- (void)dealloc
{
[socket release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to accept connection in socket of type %@! " ERRFMT,
inClass, ERRPARAM];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFAcceptFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAcceptFailedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
{
return [[[self alloc] initWithClass: class
socket: socket] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
{
self = [super initWithClass: class];
_socket = [socket retain];
_errNo = GET_SOCK_ERRNO;
return self;
}
- (void)dealloc
{
[_socket release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to accept connection in socket of type %@! " ERRFMT,
_inClass, ERRPARAM];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFAddressTranslationFailedException.h
from [ca60b34b9f]
to [9eb5a36411].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFTCPSocket;
/*!
* @brief An exception indicating the translation of an address failed.
*/
@interface OFAddressTranslationFailedException: OFException
{
OFTCPSocket *socket;
OFString *host;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) int errNo;
#endif
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFTCPSocket;
/*!
* @brief An exception indicating the translation of an address failed.
*/
@interface OFAddressTranslationFailedException: OFException
{
OFTCPSocket *_socket;
OFString *_host;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFAddressTranslationFailedException.m
from [967ab0fcff]
to [1441dd45a6].
︙ | | | ︙ | |
19
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
|
#import "OFAddressTranslationFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAddressTranslationFailedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
host: (OFString*)host
{
return [[[self alloc] initWithClass: class_
socket: socket
host: host] autorelease];
}
- initWithClass: (Class)class_
{
self = [super initWithClass: class_];
errNo = GET_AT_ERRNO;
return self;
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
host: (OFString*)host_
{
self = [super initWithClass: class_];
@try {
socket = [socket_ retain];
host = [host_ copy];
errNo = GET_AT_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[socket release];
[host release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
if (host != nil)
description = [[OFString alloc] initWithFormat:
@"The host %@ could not be translated to an address in "
@"class %@. This means that either the host was not found, "
@"there was a problem with the name server, there was a "
@"problem with your network connection or you specified an "
@"invalid host. " ERRFMT, host, inClass, AT_ERRPARAM];
else
description = [[OFString alloc] initWithFormat:
@"An address translation failed in class %@! " ERRFMT,
inClass, AT_ERRPARAM];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
- (OFString*)host
{
return host;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#import "OFAddressTranslationFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAddressTranslationFailedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
{
return [[[self alloc] initWithClass: class
socket: socket
host: host] autorelease];
}
- initWithClass: (Class)class
{
self = [super initWithClass: class];
_errNo = GET_AT_ERRNO;
return self;
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
{
self = [super initWithClass: class];
@try {
_socket = [socket retain];
_host = [host copy];
_errNo = GET_AT_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_socket release];
[_host release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
if (_host != nil)
_description = [[OFString alloc] initWithFormat:
@"The host %@ could not be translated to an address in "
@"class %@. This means that either the host was not found, "
@"there was a problem with the name server, there was a "
@"problem with your network connection or you specified an "
@"invalid host. " ERRFMT, _host, _inClass, AT_ERRPARAM];
else
_description = [[OFString alloc] initWithFormat:
@"An address translation failed in class %@! " ERRFMT,
_inClass, AT_ERRPARAM];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
- (OFString*)host
{
OF_GETTER(_host, NO)
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFAlreadyConnectedException.h
from [8c89edc113]
to [5e96c85485].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/*!
* @brief An exception indicating an attempt to connect or bind an already
* connected or bound socket.
*/
@interface OFAlreadyConnectedException: OFException
{
OFTCPSocket *socket;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
#endif
/*!
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/*!
* @brief An exception indicating an attempt to connect or bind an already
* connected or bound socket.
*/
@interface OFAlreadyConnectedException: OFException
{
OFTCPSocket *_socket;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFAlreadyConnectedException.m
from [539ea0a982]
to [8b35209312].
︙ | | | ︙ | |
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
|
#import "OFAlreadyConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAlreadyConnectedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
{
return [[[self alloc] initWithClass: class_
socket: socket] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
{
self = [super initWithClass: class_];
socket = [socket_ retain];
return self;
}
- (void)dealloc
{
[socket release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The socket of type %@ is already connected or bound and thus "
@"can't be connected or bound again!", inClass];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFAlreadyConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFAlreadyConnectedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
{
return [[[self alloc] initWithClass: class
socket: socket] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
{
self = [super initWithClass: class];
_socket = [socket retain];
return self;
}
- (void)dealloc
{
[_socket release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The socket of type %@ is already connected or bound and thus "
@"can't be connected or bound again!", _inClass];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
@end
|
Modified src/exceptions/OFBindFailedException.h
from [9ba16ce080]
to [3324f93c42].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that binding a socket failed.
*/
@interface OFBindFailedException: OFException
{
OFTCPSocket *socket;
OFString *host;
uint16_t port;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;
|
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that binding a socket failed.
*/
@interface OFBindFailedException: OFException
{
OFTCPSocket *_socket;
OFString *_host;
uint16_t _port;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFBindFailedException.m
from [4d941c04f6]
to [04bd4c8eb2].
︙ | | | ︙ | |
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
|
#import "OFBindFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFBindFailedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
return [[[self alloc] initWithClass: class_
socket: socket
host: host
port: port] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
host: (OFString*)host_
port: (uint16_t)port_
{
self = [super initWithClass: class_];
@try {
socket = [socket_ retain];
host = [host_ copy];
port = port_;
errNo = GET_SOCK_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[socket release];
[host release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Binding to port %" @PRIu16 @" on host %@ failed in class %@! "
ERRFMT, port, host, inClass, ERRPARAM];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
- (OFString*)host
{
OF_GETTER(host, NO)
}
- (uint16_t)port
{
return port;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFBindFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFBindFailedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
return [[[self alloc] initWithClass: class
socket: socket
host: host
port: port] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
self = [super initWithClass: class];
@try {
_socket = [socket retain];
_host = [host copy];
_port = port;
_errNo = GET_SOCK_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_socket release];
[_host release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Binding to port %" @PRIu16 @" on host %@ failed in class %@! "
ERRFMT, _port, _host, _inClass, ERRPARAM];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
- (OFString*)host
{
OF_GETTER(_host, NO)
}
- (uint16_t)port
{
return _port;
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFChangeDirectoryFailedException.h
from [e713af3485]
to [4e7164768a].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating changing to a directory failed
*/
@interface OFChangeDirectoryFailedException: OFException
{
OFString *path;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating changing to a directory failed
*/
@interface OFChangeDirectoryFailedException: OFException
{
OFString *_path;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFChangeDirectoryFailedException.m
from [ba07871883]
to [a9860585f3].
︙ | | | ︙ | |
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
|
#import "OFChangeDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFChangeDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path_
{
return [[[self alloc] initWithClass: class_
path: path_] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to change to directory %@ in class %@! " ERRFMT, path,
inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFChangeDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFChangeDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
{
return [[[self alloc] initWithClass: class
path: path] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to change to directory %@ in class %@! " ERRFMT, _path,
_inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
@end
|
Modified src/exceptions/OFChangeFileModeFailedException.h
from [c2c327670a]
to [ff2f6d8da0].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#import "OFException.h"
/*!
* @brief An exception indicating that changing the mode of a file failed.
*/
@interface OFChangeFileModeFailedException: OFException
{
OFString *path;
mode_t mode;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) mode_t mode;
@property (readonly) int errNo;
#endif
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#import "OFException.h"
/*!
* @brief An exception indicating that changing the mode of a file failed.
*/
@interface OFChangeFileModeFailedException: OFException
{
OFString *_path;
mode_t _mode;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) mode_t mode;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFChangeFileModeFailedException.m
from [a59ee4c2b7]
to [319db3107f].
︙ | | | ︙ | |
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
|
#import "OFChangeFileModeFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFChangeFileModeFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path
mode: (mode_t)mode
{
return [[[self alloc] initWithClass: class_
path: path
mode: mode] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
mode: (mode_t)mode_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
mode = mode_;
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to change mode for file %@ to %d in class %@! " ERRFMT,
path, mode, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
- (mode_t)mode
{
return mode;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFChangeFileModeFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFChangeFileModeFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
mode: (mode_t)mode
{
return [[[self alloc] initWithClass: class
path: path
mode: mode] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
mode: (mode_t)mode
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_mode = mode;
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to change mode for file %@ to %d in class %@! " ERRFMT,
_path, _mode, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
- (mode_t)mode
{
return _mode;
}
@end
|
Modified src/exceptions/OFChangeFileOwnerFailedException.h
from [ac5a1c7a55]
to [c53d35405c].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#ifndef _WIN32
/*!
* @brief An exception indicating that changing the owner of a file failed.
*/
@interface OFChangeFileOwnerFailedException: OFException
{
OFString *path;
OFString *owner;
OFString *group;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly, copy, nonatomic) OFString *owner;
@property (readonly, copy, nonatomic) OFString *group;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased change file owner failed exception.
*
* @param class_ The class of the object which caused the exception
|
|
<
<
|
|
<
<
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#ifndef _WIN32
/*!
* @brief An exception indicating that changing the owner of a file failed.
*/
@interface OFChangeFileOwnerFailedException: OFException
{
OFString *_path, *_owner, *_group;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path, *owner, *group;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased change file owner failed exception.
*
* @param class_ The class of the object which caused the exception
|
︙ | | | ︙ | |
Modified src/exceptions/OFChangeFileOwnerFailedException.m
from [7ba6b6f15a]
to [0b00f53cf5].
︙ | | | ︙ | |
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
119
120
121
|
#import "OFChangeFileOwnerFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFChangeFileOwnerFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path
owner: (OFString*)owner
group: (OFString*)group
{
return [[[self alloc] initWithClass: class_
path: path
owner: owner
group: group] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
owner: (OFString*)owner_
group: (OFString*)group_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
owner = [owner_ copy];
group = [group_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[owner release];
[group release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
if (group == nil)
description = [[OFString alloc] initWithFormat:
@"Failed to change owner for file %@ to %@ in class %@! "
ERRFMT, path, owner, inClass, ERRPARAM];
else if (owner == nil)
description = [[OFString alloc] initWithFormat:
@"Failed to change group for file %@ to %@ in class %@! "
ERRFMT, path, group, inClass, ERRPARAM];
else
description = [[OFString alloc] initWithFormat:
@"Failed to change owner for file %@ to %@:%@ in class %@! "
ERRFMT, path, owner, group, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
- (OFString*)owner
{
OF_GETTER(owner, NO)
}
- (OFString*)group
{
OF_GETTER(group, NO)
}
@end
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
119
120
121
|
#import "OFChangeFileOwnerFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFChangeFileOwnerFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
owner: (OFString*)owner
group: (OFString*)group
{
return [[[self alloc] initWithClass: class
path: path
owner: owner
group: group] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
owner: (OFString*)owner
group: (OFString*)group
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_owner = [owner copy];
_group = [group copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[_owner release];
[_group release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
if (_group == nil)
_description = [[OFString alloc] initWithFormat:
@"Failed to change owner for file %@ to %@ in class %@! "
ERRFMT, _path, _owner, _inClass, ERRPARAM];
else if (_owner == nil)
_description = [[OFString alloc] initWithFormat:
@"Failed to change group for file %@ to %@ in class %@! "
ERRFMT, _path, _group, _inClass, ERRPARAM];
else
_description = [[OFString alloc] initWithFormat:
@"Failed to change owner for file %@ to %@:%@ in class %@! "
ERRFMT, _path, _owner, _group, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
- (OFString*)owner
{
OF_GETTER(_owner, NO)
}
- (OFString*)group
{
OF_GETTER(_group, NO)
}
@end
#endif
|
Modified src/exceptions/OFConditionBroadcastFailedException.h
from [37863f05fb]
to [8280acbac2].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating broadcasting a condition failed.
*/
@interface OFConditionBroadcastFailedException: OFException
{
OFCondition *condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating broadcasting a condition failed.
*/
@interface OFConditionBroadcastFailedException: OFException
{
OFCondition *_condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFConditionBroadcastFailedException.m
from [239bfd4ef8]
to [cc9bbab33a].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFConditionBroadcastFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionBroadcastFailedException
+ (instancetype)exceptionWithClass: (Class)class_
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class_
condition: condition] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
condition: (OFCondition*)condition_
{
self = [super initWithClass: class_];
condition = [condition_ retain];
return self;
}
- (void)dealloc
{
[condition release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Broadcasting a condition of type %@ failed!", inClass];
return description;
}
- (OFCondition*)condition
{
OF_GETTER(condition, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFConditionBroadcastFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionBroadcastFailedException
+ (instancetype)exceptionWithClass: (Class)class
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class
condition: condition] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
condition: (OFCondition*)condition
{
self = [super initWithClass: class];
_condition = [condition retain];
return self;
}
- (void)dealloc
{
[_condition release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Broadcasting a condition of type %@ failed!", _inClass];
return _description;
}
- (OFCondition*)condition
{
OF_GETTER(_condition, NO)
}
@end
|
Modified src/exceptions/OFConditionSignalFailedException.h
from [1882a0cdda]
to [ce8cf52835].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating signaling a condition failed.
*/
@interface OFConditionSignalFailedException: OFException
{
OFCondition *condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating signaling a condition failed.
*/
@interface OFConditionSignalFailedException: OFException
{
OFCondition *_condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFConditionSignalFailedException.m
from [e9f398f7d6]
to [3da88ce5d9].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFConditionSignalFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionSignalFailedException
+ (instancetype)exceptionWithClass: (Class)class_
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class_
condition: condition] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
condition: (OFCondition*)condition_
{
self = [super initWithClass: class_];
condition = [condition_ retain];
return self;
}
- (void)dealloc
{
[condition release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Signaling a condition of type %@ failed!", inClass];
return description;
}
- (OFCondition*)condition
{
OF_GETTER(condition, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFConditionSignalFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionSignalFailedException
+ (instancetype)exceptionWithClass: (Class)class
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class
condition: condition] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
condition: (OFCondition*)condition
{
self = [super initWithClass: class];
_condition = [condition retain];
return self;
}
- (void)dealloc
{
[_condition release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Signaling a condition of type %@ failed!", _inClass];
return _description;
}
- (OFCondition*)condition
{
OF_GETTER(_condition, NO)
}
@end
|
Modified src/exceptions/OFConditionStillWaitingException.h
from [0abdd32fbd]
to [fdfddc2862].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/*!
* @brief An exception indicating that a thread is still waiting for a
* condition.
*/
@interface OFConditionStillWaitingException: OFException
{
OFCondition *condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/*!
* @brief An exception indicating that a thread is still waiting for a
* condition.
*/
@interface OFConditionStillWaitingException: OFException
{
OFCondition *_condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFConditionStillWaitingException.m
from [c432acb363]
to [ccf984394c].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFConditionStillWaitingException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionStillWaitingException
+ (instancetype)exceptionWithClass: (Class)class_
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class_
condition: condition] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
condition: (OFCondition*)condition_
{
self = [super initWithClass: class_];
condition = [condition_ retain];
return self;
}
- (void)dealloc
{
[condition release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Deallocation of a condition of type %@ was tried, even though a "
@"thread was still waiting for it!", inClass];
return description;
}
- (OFCondition*)condition
{
OF_GETTER(condition, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFConditionStillWaitingException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionStillWaitingException
+ (instancetype)exceptionWithClass: (Class)class
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class
condition: condition] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
condition: (OFCondition*)condition
{
self = [super initWithClass: class];
_condition = [condition retain];
return self;
}
- (void)dealloc
{
[_condition release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Deallocation of a condition of type %@ was tried, even though a "
@"thread was still waiting for it!", _inClass];
return _description;
}
- (OFCondition*)condition
{
OF_GETTER(_condition, NO)
}
@end
|
Modified src/exceptions/OFConditionWaitFailedException.h
from [1446fc3245]
to [c95a31d0d6].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating waiting for a condition failed.
*/
@interface OFConditionWaitFailedException: OFException
{
OFCondition *condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFCondition;
/*!
* @brief An exception indicating waiting for a condition failed.
*/
@interface OFConditionWaitFailedException: OFException
{
OFCondition *_condition;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFCondition *condition;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFConditionWaitFailedException.m
from [1c3c12a3c1]
to [8bbc25a706].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFConditionWaitFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionWaitFailedException
+ (instancetype)exceptionWithClass: (Class)class_
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class_
condition: condition] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
condition: (OFCondition*)condition_
{
self = [super initWithClass: class_];
condition = [condition_ retain];
return self;
}
- (void)dealloc
{
[condition release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Waiting for a condition of type %@ failed!", inClass];
return description;
}
- (OFCondition*)condition
{
OF_GETTER(condition, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFConditionWaitFailedException.h"
#import "OFString.h"
#import "OFCondition.h"
@implementation OFConditionWaitFailedException
+ (instancetype)exceptionWithClass: (Class)class
condition: (OFCondition*)condition
{
return [[[self alloc] initWithClass: class
condition: condition] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
condition: (OFCondition*)condition
{
self = [super initWithClass: class];
_condition = [condition retain];
return self;
}
- (void)dealloc
{
[_condition release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Waiting for a condition of type %@ failed!", _inClass];
return _description;
}
- (OFCondition*)condition
{
OF_GETTER(_condition, NO)
}
@end
|
Modified src/exceptions/OFConnectionFailedException.h
from [98696826d6]
to [6e0a8c3716].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that a connection could not be established.
*/
@interface OFConnectionFailedException: OFException
{
OFTCPSocket *socket;
OFString *host;
uint16_t port;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;
|
|
|
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that a connection could not be established.
*/
@interface OFConnectionFailedException: OFException
{
OFTCPSocket *_socket;
OFString *_host;
uint16_t _port;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly, copy, nonatomic) OFString *host;
@property (readonly) uint16_t port;
@property (readonly) int errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFConnectionFailedException.m
from [122bf660e2]
to [ed77afb6a3].
︙ | | | ︙ | |
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
|
#import "OFConnectionFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFConnectionFailedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
return [[[self alloc] initWithClass: class_
socket: socket
host: host
port: port] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
host: (OFString*)host_
port: (uint16_t)port_
{
self = [super initWithClass: class_];
@try {
socket = [socket_ retain];
host = [host_ copy];
port = port_;
errNo = GET_SOCK_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[socket release];
[host release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"A connection to %@ on port %" @PRIu16 @" could not be "
@"established in class %@! " ERRFMT, host, port, inClass, ERRPARAM];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
- (OFString*)host
{
OF_GETTER(host, NO)
}
- (uint16_t)port
{
return port;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
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
|
#import "OFConnectionFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFConnectionFailedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
return [[[self alloc] initWithClass: class
socket: socket
host: host
port: port] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
host: (OFString*)host
port: (uint16_t)port
{
self = [super initWithClass: class];
@try {
_socket = [socket retain];
_host = [host copy];
_port = port;
_errNo = GET_SOCK_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_socket release];
[_host release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"A connection to %@ on port %" @PRIu16 @" could not be "
@"established in class %@! " ERRFMT, _host, _port, _inClass,
ERRPARAM];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
- (OFString*)host
{
OF_GETTER(_host, NO)
}
- (uint16_t)port
{
return _port;
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFCopyFileFailedException.h
from [999eac0ccf]
to [8e2325479f].
︙ | | | ︙ | |
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating that copying a file failed.
*/
@interface OFCopyFileFailedException: OFException
{
OFString *sourcePath;
OFString *destinationPath;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased copy file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The original path
* @param destination The new path
* @return A new, autoreleased copy file failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Initializes an already allocated copy file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The original path
* @param destination The new path
* @return An initialized copy file failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
<
|
|
|
|
|
|
|
|
|
|
|
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating that copying a file failed.
*/
@interface OFCopyFileFailedException: OFException
{
OFString *_sourcePath, *_destinationPath;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased copy file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The original path
* @param destinationPath The new path
* @return A new, autoreleased copy file failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Initializes an already allocated copy file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The original path
* @param destinationPath The new path
* @return An initialized copy file failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFCopyFileFailedException.m
from [c7d13f40bb]
to [c8f8b1a133].
︙ | | | ︙ | |
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
|
#import "OFCopyFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFCopyFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
return [[[self alloc] initWithClass: class_
sourcePath: source
destinationPath: destination] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
self = [super initWithClass: class_];
@try {
sourcePath = [source copy];
destinationPath = [destination copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sourcePath release];
[destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to copy file %@ to %@ in class %@! " ERRFMT,
sourcePath, destinationPath, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(destinationPath, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFCopyFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFCopyFileFailedException
+ (instancetype)exceptionWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
return [[[self alloc] initWithClass: class
sourcePath: sourcePath
destinationPath: destinationPath] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
self = [super initWithClass: class];
@try {
_sourcePath = [sourcePath copy];
_destinationPath = [destinationPath copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_sourcePath release];
[_destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to copy file %@ to %@ in class %@! " ERRFMT,
_sourcePath, _destinationPath, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(_sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(_destinationPath, NO)
}
@end
|
Modified src/exceptions/OFCreateDirectoryFailedException.h
from [a59eadf735]
to [34b0a07f1e].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating a directory couldn't be created.
*/
@interface OFCreateDirectoryFailedException: OFException
{
OFString *path;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating a directory couldn't be created.
*/
@interface OFCreateDirectoryFailedException: OFException
{
OFString *_path;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFCreateDirectoryFailedException.m
from [2a62eb5d8d]
to [029fb950d4].
︙ | | | ︙ | |
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
|
#import "OFCreateDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFCreateDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path_
{
return [[[self alloc] initWithClass: class_
path: path_] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to create directory %@ in class %@! " ERRFMT, path,
inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFCreateDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFCreateDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
{
return [[[self alloc] initWithClass: class
path: path] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to create directory %@ in class %@! " ERRFMT, _path,
_inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
@end
|
Modified src/exceptions/OFDeleteDirectoryFailedException.h
from [ecc67ea15b]
to [9ce6ca0f5f].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating that deleting a directory failed.
*/
@interface OFDeleteDirectoryFailedException: OFException
{
OFString *path;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating that deleting a directory failed.
*/
@interface OFDeleteDirectoryFailedException: OFException
{
OFString *_path;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFDeleteDirectoryFailedException.m
from [c0c7391dfd]
to [55773e30a9].
︙ | | | ︙ | |
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
|
#import "OFDeleteDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFDeleteDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path_
{
return [[[self alloc] initWithClass: class_
path: path_] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to delete directory %@ in class %@! " ERRFMT, path,
inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFDeleteDirectoryFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFDeleteDirectoryFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path_
{
return [[[self alloc] initWithClass: class
path: path_] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to delete directory %@ in class %@! " ERRFMT, _path,
_inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
@end
|
Modified src/exceptions/OFDeleteFileFailedException.h
from [e97aa02e0b]
to [ed836376b8].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating that deleting a file failed.
*/
@interface OFDeleteFileFailedException: OFException
{
OFString *path;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFException.h"
/*!
* @brief An exception indicating that deleting a file failed.
*/
@interface OFDeleteFileFailedException: OFException
{
OFString *_path;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly) int errNo;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFDeleteFileFailedException.m
from [688b15cb7d]
to [65143331f2].
︙ | | | ︙ | |
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
|
#import "OFDeleteFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFDeleteFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path_
{
return [[[self alloc] initWithClass: class_
path: path_] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to delete file %@ in class %@! " ERRFMT, path, inClass,
ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFDeleteFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFDeleteFileFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
{
return [[[self alloc] initWithClass: class
path: path] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to delete file %@ in class %@! " ERRFMT, _path, _inClass,
ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
@end
|
Modified src/exceptions/OFEnumerationMutationException.h
from [7938f605d2]
to [878a08d7a2].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that a mutation was detected during
* enumeration.
*/
@interface OFEnumerationMutationException: OFException
{
id object;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id object;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that a mutation was detected during
* enumeration.
*/
@interface OFEnumerationMutationException: OFException
{
id _object;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id object;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFEnumerationMutationException.m
from [1d37cda0c7]
to [d10005f035].
︙ | | | ︙ | |
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
|
#import "OFEnumerationMutationException.h"
#import "OFString.h"
#import "common.h"
@implementation OFEnumerationMutationException
+ (instancetype)exceptionWithClass: (Class)class_
object: (id)object
{
return [[[self alloc] initWithClass: class_
object: object] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
object: (id)object_
{
self = [super initWithClass: class_];
object = [object_ retain];
return self;
}
- (void)dealloc
{
[object release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Object of class %@ was mutated during enumeration!", inClass];
return description;
}
- (id)object
{
OF_GETTER(object, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFEnumerationMutationException.h"
#import "OFString.h"
#import "common.h"
@implementation OFEnumerationMutationException
+ (instancetype)exceptionWithClass: (Class)class
object: (id)object
{
return [[[self alloc] initWithClass: class
object: object] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
object: (id)object
{
self = [super initWithClass: class];
_object = [object retain];
return self;
}
- (void)dealloc
{
[_object release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Object of class %@ was mutated during enumeration!", _inClass];
return _description;
}
- (id)object
{
OF_GETTER(_object, NO)
}
@end
|
Modified src/exceptions/OFException.h
from [93f8f3dd32]
to [0e7a48ed31].
︙ | | | ︙ | |
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
* @brief The base class for all exceptions in ObjFW
*
* The OFException class is the base class for all exceptions in ObjFW, except
* the OFAllocFailedException.
*/
@interface OFException: OFObject
{
Class inClass;
OFString *description;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) Class inClass;
#endif
/*!
|
|
|
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
* @brief The base class for all exceptions in ObjFW
*
* The OFException class is the base class for all exceptions in ObjFW, except
* the OFAllocFailedException.
*/
@interface OFException: OFObject
{
Class _inClass;
OFString *_description;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) Class inClass;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFException.m
from [17d551971c]
to [0dacb298b3].
︙ | | | ︙ | |
18
19
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
|
#include <stdlib.h>
#import "OFException.h"
#import "OFString.h"
@implementation OFException
+ (instancetype)exceptionWithClass: (Class)class_
{
return [[[self alloc] initWithClass: class_] autorelease];
}
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
{
self = [super init];
inClass = class_;
return self;
}
- (void)dealloc
{
[description release];
[super dealloc];
}
- (Class)inClass
{
return inClass;
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"An exception of class %@ occurred in class %@!",
object_getClass(self), inClass];
return description;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#include <stdlib.h>
#import "OFException.h"
#import "OFString.h"
@implementation OFException
+ (instancetype)exceptionWithClass: (Class)class
{
return [[[self alloc] initWithClass: class] autorelease];
}
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
{
self = [super init];
_inClass = class;
return self;
}
- (void)dealloc
{
[_description release];
[super dealloc];
}
- (Class)inClass
{
return _inClass;
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"An exception of class %@ occurred in class %@!",
object_getClass(self), _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFHTTPRequestFailedException.h
from [5db7e230ae]
to [e63622a3c6].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFHTTPRequestReply;
/*!
* @brief An exception indicating that a HTTP request failed.
*/
@interface OFHTTPRequestFailedException: OFException
{
OFHTTPRequest *request;
OFHTTPRequestReply *reply;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHTTPRequest *request;
@property (readonly, retain, nonatomic) OFHTTPRequestReply *reply;
#endif
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@class OFHTTPRequestReply;
/*!
* @brief An exception indicating that a HTTP request failed.
*/
@interface OFHTTPRequestFailedException: OFException
{
OFHTTPRequest *_request;
OFHTTPRequestReply *_reply;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHTTPRequest *request;
@property (readonly, retain, nonatomic) OFHTTPRequestReply *reply;
#endif
|
︙ | | | ︙ | |
Modified src/exceptions/OFHTTPRequestFailedException.m
from [c529841d84]
to [6a16e70139].
︙ | | | ︙ | |
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
|
#import "OFHTTPRequest.h"
#import "OFHTTPRequestReply.h"
#import "autorelease.h"
#import "common.h"
@implementation OFHTTPRequestFailedException
+ (instancetype)exceptionWithClass: (Class)class_
request: (OFHTTPRequest*)request
reply: (OFHTTPRequestReply*)reply
{
return [[[self alloc] initWithClass: class_
request: request
reply: reply] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
request: (OFHTTPRequest*)request_
reply: (OFHTTPRequestReply*)reply_
{
self = [super initWithClass: class_];
request = [request_ retain];
reply = [reply_ retain];
return self;
}
- (void)dealloc
{
[request release];
[reply release];
[super dealloc];
}
- (OFString*)description
{
void *pool;
const char *type = "(unknown)";
if (description != nil)
return description;
switch ([request requestType]) {
case OF_HTTP_REQUEST_TYPE_GET:
type = "GET";
break;
case OF_HTTP_REQUEST_TYPE_HEAD:
type = "HEAD";
break;
case OF_HTTP_REQUEST_TYPE_POST:
type = "POST";
break;
}
pool = objc_autoreleasePoolPush();
description = [[OFString alloc] initWithFormat:
@"A HTTP %s request in class %@ with URL %@ failed with code %d",
type, inClass, [request URL], [reply statusCode]];
objc_autoreleasePoolPop(pool);
return description;
}
- (OFHTTPRequest*)request
{
OF_GETTER(request, NO)
}
- (OFHTTPRequestReply*)reply
{
OF_GETTER(reply, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFHTTPRequest.h"
#import "OFHTTPRequestReply.h"
#import "autorelease.h"
#import "common.h"
@implementation OFHTTPRequestFailedException
+ (instancetype)exceptionWithClass: (Class)class
request: (OFHTTPRequest*)request
reply: (OFHTTPRequestReply*)reply
{
return [[[self alloc] initWithClass: class
request: request
reply: reply] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
request: (OFHTTPRequest*)request
reply: (OFHTTPRequestReply*)reply
{
self = [super initWithClass: class];
_request = [request retain];
_reply = [reply retain];
return self;
}
- (void)dealloc
{
[_request release];
[_reply release];
[super dealloc];
}
- (OFString*)description
{
void *pool;
const char *type = "(unknown)";
if (_description != nil)
return _description;
switch ([_request requestType]) {
case OF_HTTP_REQUEST_TYPE_GET:
type = "GET";
break;
case OF_HTTP_REQUEST_TYPE_HEAD:
type = "HEAD";
break;
case OF_HTTP_REQUEST_TYPE_POST:
type = "POST";
break;
}
pool = objc_autoreleasePoolPush();
_description = [[OFString alloc] initWithFormat:
@"A HTTP %s request in class %@ with URL %@ failed with code %d",
type, _inClass, [_request URL], [_reply statusCode]];
objc_autoreleasePoolPop(pool);
return _description;
}
- (OFHTTPRequest*)request
{
OF_GETTER(_request, NO)
}
- (OFHTTPRequestReply*)reply
{
OF_GETTER(_reply, NO)
}
@end
|
Modified src/exceptions/OFHashAlreadyCalculatedException.h
from [9afa896f63]
to [3c8cb83bb8].
︙ | | | ︙ | |
19
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
|
@class OFHash;
/*!
* @brief An exception indicating that the hash has already been calculated.
*/
@interface OFHashAlreadyCalculatedException: OFException
{
OFHash *hashObject;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHash *hashObject;
#endif
/*!
* @brief Creates a new, autoreleased hash already calculated exception.
*
* @param class_ The class of the object which caused the exception
* @param hash The hash which has already been calculated
* @return A new, autoreleased hash already calculated exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
hash: (OFHash*)hash;
/*!
* @brief Initializes an already allocated hash already calculated exception.
*
* @param class_ The class of the object which caused the exception
* @param hash The hash which has already been calculated
* @return An initialized hash already calculated exception
*/
- initWithClass: (Class)class_
hash: (OFHash*)hash;
/*!
* @brief Returns the hash which has already been calculated.
*
* @return The hash which has already been calculated
*/
- (OFHash*)hashObject;
@end
|
|
|
|
|
|
|
19
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
|
@class OFHash;
/*!
* @brief An exception indicating that the hash has already been calculated.
*/
@interface OFHashAlreadyCalculatedException: OFException
{
OFHash *_hashObject;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFHash *hashObject;
#endif
/*!
* @brief Creates a new, autoreleased hash already calculated exception.
*
* @param class_ The class of the object which caused the exception
* @param hashObject The hash which has already been calculated
* @return A new, autoreleased hash already calculated exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
hash: (OFHash*)hashObject;
/*!
* @brief Initializes an already allocated hash already calculated exception.
*
* @param class_ The class of the object which caused the exception
* @param hashObject The hash which has already been calculated
* @return An initialized hash already calculated exception
*/
- initWithClass: (Class)class_
hash: (OFHash*)hashObject;
/*!
* @brief Returns the hash which has already been calculated.
*
* @return The hash which has already been calculated
*/
- (OFHash*)hashObject;
@end
|
Modified src/exceptions/OFHashAlreadyCalculatedException.m
from [45da32b1b3]
to [1c6147719c].
︙ | | | ︙ | |
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
|
#import "OFHashAlreadyCalculatedException.h"
#import "OFString.h"
#import "OFHash.h"
#import "common.h"
@implementation OFHashAlreadyCalculatedException
+ (instancetype)exceptionWithClass: (Class)class_
hash: (OFHash*)hash
{
return [[[self alloc] initWithClass: class_
hash: hash] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
hash: (OFHash*)hash
{
self = [super initWithClass: class_];
hashObject = [hash retain];
return self;
}
- (void)dealloc
{
[hashObject release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The hash has already been calculated in class %@ and thus no new "
@"data can be added", inClass];
return description;
}
- (OFHash*)hashObject
{
OF_GETTER(hashObject, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFHashAlreadyCalculatedException.h"
#import "OFString.h"
#import "OFHash.h"
#import "common.h"
@implementation OFHashAlreadyCalculatedException
+ (instancetype)exceptionWithClass: (Class)class
hash: (OFHash*)hash
{
return [[[self alloc] initWithClass: class
hash: hash] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
hash: (OFHash*)hashObject
{
self = [super initWithClass: class];
_hashObject = [hashObject retain];
return self;
}
- (void)dealloc
{
[_hashObject release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The hash has already been calculated in class %@ and thus no new "
@"data can be added", _inClass];
return _description;
}
- (OFHash*)hashObject
{
OF_GETTER(_hashObject, NO)
}
@end
|
Modified src/exceptions/OFInitializationFailedException.m
from [c6c6b9a8bb]
to [5f9ac7b48a].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInitializationFailedException.h"
#import "OFString.h"
@implementation OFInitializationFailedException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Initialization failed for or in class %@!", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInitializationFailedException.h"
#import "OFString.h"
@implementation OFInitializationFailedException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Initialization failed for or in class %@!", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFInvalidArgumentException.h
from [aeaa01bea3]
to [6c06e4e596].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFException.h"
/*!
* @brief An exception indicating that the argument is invalid for this method.
*/
@interface OFInvalidArgumentException: OFException
{
SEL selector;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif
/*!
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFException.h"
/*!
* @brief An exception indicating that the argument is invalid for this method.
*/
@interface OFInvalidArgumentException: OFException
{
SEL _selector;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFInvalidArgumentException.m
from [378595486c]
to [98b7296261].
︙ | | | ︙ | |
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
|
#import "OFInvalidArgumentException.h"
#import "OFString.h"
#import "common.h"
@implementation OFInvalidArgumentException
+ (instancetype)exceptionWithClass: (Class)class_
selector: (SEL)selector_
{
return [[[self alloc] initWithClass: class_
selector: selector_] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
selector: (SEL)selector_
{
self = [super initWithClass: class_];
selector = selector_;
return self;
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The argument or receiver for method %s of class %@ is invalid!",
sel_getName(selector), inClass];
return description;
}
- (SEL)selector
{
return selector;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFInvalidArgumentException.h"
#import "OFString.h"
#import "common.h"
@implementation OFInvalidArgumentException
+ (instancetype)exceptionWithClass: (Class)class
selector: (SEL)selector
{
return [[[self alloc] initWithClass: class
selector: selector] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
selector: (SEL)selector
{
self = [super initWithClass: class];
_selector = selector;
return self;
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The argument or receiver for method %s of class %@ is invalid!",
sel_getName(_selector), _inClass];
return _description;
}
- (SEL)selector
{
return _selector;
}
@end
|
Modified src/exceptions/OFInvalidEncodingException.m
from [65d6f47aba]
to [890bb48a2b].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidEncodingException.h"
#import "OFString.h"
@implementation OFInvalidEncodingException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The encoding is invalid for class %@!", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidEncodingException.h"
#import "OFString.h"
@implementation OFInvalidEncodingException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The encoding is invalid for class %@!", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFInvalidFormatException.m
from [01a1973b97]
to [7b073a6102].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidFormatException.h"
#import "OFString.h"
@implementation OFInvalidFormatException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The format is invalid for class %@!", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidFormatException.h"
#import "OFString.h"
@implementation OFInvalidFormatException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The format is invalid for class %@!", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFInvalidJSONException.h
from [15c9f96f98]
to [e45d7a3ec9].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFException.h"
/*!
* @brief An exception indicating a JSON representation is invalid.
*/
@interface OFInvalidJSONException: OFException
{
size_t line;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t line;
#endif
/*!
|
|
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import "OFException.h"
/*!
* @brief An exception indicating a JSON representation is invalid.
*/
@interface OFInvalidJSONException: OFException
{
size_t _line;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t line;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFInvalidJSONException.m
from [c2b4bc6b4c]
to [477577db36].
︙ | | | ︙ | |
18
19
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
|
#include <stdlib.h>
#import "OFInvalidJSONException.h"
#import "OFString.h"
@implementation OFInvalidJSONException
+ (instancetype)exceptionWithClass: (Class)class_
line: (size_t)line
{
return [[[self alloc] initWithClass: class_
line: line] autorelease];
}
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
line: (size_t)line_
{
self = [super initWithClass: class_];
line = line_;
return self;
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The JSON representation class %@ tried to parse is invalid in "
@"line %zd!", inClass, line];
return description;
}
- (size_t)line
{
return line;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#include <stdlib.h>
#import "OFInvalidJSONException.h"
#import "OFString.h"
@implementation OFInvalidJSONException
+ (instancetype)exceptionWithClass: (Class)class
line: (size_t)line
{
return [[[self alloc] initWithClass: class
line: line] autorelease];
}
- init
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
line: (size_t)line
{
self = [super initWithClass: class];
_line = line;
return self;
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The JSON representation class %@ tried to parse is invalid in "
@"line %zd!", _inClass, _line];
return _description;
}
- (size_t)line
{
return _line;
}
@end
|
Modified src/exceptions/OFInvalidServerReplyException.m
from [6f32896ab7]
to [33d6295197].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidServerReplyException.h"
#import "OFString.h"
@implementation OFInvalidServerReplyException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Got an invalid reply from the server in class %@", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFInvalidServerReplyException.h"
#import "OFString.h"
@implementation OFInvalidServerReplyException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Got an invalid reply from the server in class %@", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFLinkFailedException.h
from [dd1a6acbbb]
to [2ff6890222].
︙ | | | ︙ | |
18
19
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
|
#ifndef _WIN32
/*!
* @brief An exception indicating that creating a link failed.
*/
@interface OFLinkFailedException: OFException
{
OFString *sourcePath;
OFString *destinationPath;
int errNo;
}
# ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
# endif
/*!
* @brief Creates a new, autoreleased link failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The source for the link
* @param destination The destination for the link
* @return A new, autoreleased link failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Initializes an already allocated link failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The source for the link
* @param destination The destination for the link
* @return An initialized link failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
<
|
|
|
<
|
|
|
|
|
|
|
|
|
18
19
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
|
#ifndef _WIN32
/*!
* @brief An exception indicating that creating a link failed.
*/
@interface OFLinkFailedException: OFException
{
OFString *_sourcePath, *_destinationPath;
int _errNo;
}
# ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly) int errNo;
# endif
/*!
* @brief Creates a new, autoreleased link failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The source for the link
* @param destinationPath The destination for the link
* @return A new, autoreleased link failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Initializes an already allocated link failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The source for the link
* @param destinationPath The destination for the link
* @return An initialized link failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFLinkFailedException.m
from [358646961f]
to [f22db317c8].
︙ | | | ︙ | |
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
|
#import "OFLinkFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFLinkFailedException
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
return [[[self alloc] initWithClass: class_
sourcePath: source
destinationPath: destination] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
self = [super initWithClass: class_];
@try {
sourcePath = [source copy];
destinationPath = [destination copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sourcePath release];
[destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to link file %@ to %@ in class %@! " ERRFMT, sourcePath,
destinationPath, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(destinationPath, NO)
}
@end
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFLinkFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFLinkFailedException
+ (instancetype)exceptionWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
return [[[self alloc] initWithClass: class
sourcePath: sourcePath
destinationPath: destinationPath] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
self = [super initWithClass: class];
@try {
_sourcePath = [sourcePath copy];
_destinationPath = [destinationPath copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_sourcePath release];
[_destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to link file %@ to %@ in class %@! " ERRFMT, _sourcePath,
_destinationPath, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(_sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(_destinationPath, NO)
}
@end
#endif
|
Modified src/exceptions/OFListenFailedException.h
from [821019a0e7]
to [9a332b8a67].
︙ | | | ︙ | |
19
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
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that listening on the socket failed.
*/
@interface OFListenFailedException: OFException
{
OFTCPSocket *socket;
int backLog;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int backLog;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased listen failed exception.
*
* @param class_ The class of the object which caused the exception
* @param socket The socket which failed to listen
* @param backlog The requested size of the back log
* @return A new, autoreleased listen failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
backLog: (int)backlog;
/*!
* @brief Initializes an already allocated listen failed exception
*
* @param class_ The class of the object which caused the exception
* @param socket The socket which failed to listen
* @param backlog The requested size of the back log
* @return An initialized listen failed exception
*/
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket
backLog: (int)backlog;
/*!
* @brief Returns the socket which failed to listen.
*
* @return The socket which failed to listen
*/
- (OFTCPSocket*)socket;
|
|
|
<
|
<
|
|
|
|
|
19
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
|
@class OFTCPSocket;
/*!
* @brief An exception indicating that listening on the socket failed.
*/
@interface OFListenFailedException: OFException
{
OFTCPSocket *_socket;
int _backLog, _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFTCPSocket *socket;
@property (readonly) int backLog, errNo;
#endif
/*!
* @brief Creates a new, autoreleased listen failed exception.
*
* @param class_ The class of the object which caused the exception
* @param socket The socket which failed to listen
* @param backLog The requested size of the back log
* @return A new, autoreleased listen failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
backLog: (int)backLog;
/*!
* @brief Initializes an already allocated listen failed exception
*
* @param class_ The class of the object which caused the exception
* @param socket The socket which failed to listen
* @param backLog The requested size of the back log
* @return An initialized listen failed exception
*/
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket
backLog: (int)backLog;
/*!
* @brief Returns the socket which failed to listen.
*
* @return The socket which failed to listen
*/
- (OFTCPSocket*)socket;
|
︙ | | | ︙ | |
Modified src/exceptions/OFListenFailedException.m
from [8bcf2672cd]
to [df82ad09d2].
︙ | | | ︙ | |
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
|
#import "OFListenFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFListenFailedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFTCPSocket*)socket
backLog: (int)backlog
{
return [[[self alloc] initWithClass: class_
socket: socket
backLog: backlog] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFTCPSocket*)socket_
backLog: (int)backlog
{
self = [super initWithClass: class_];
socket = [socket_ retain];
backLog = backlog;
errNo = GET_SOCK_ERRNO;
return self;
}
- (void)dealloc
{
[socket release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to listen in socket of type %@ with a back log of %d! "
ERRFMT, inClass, backLog, ERRPARAM];
return description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(socket, NO)
}
- (int)backLog
{
return backLog;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFListenFailedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFListenFailedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFTCPSocket*)socket
backLog: (int)backLog
{
return [[[self alloc] initWithClass: class
socket: socket
backLog: backLog] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFTCPSocket*)socket
backLog: (int)backLog
{
self = [super initWithClass: class];
_socket = [socket retain];
_backLog = backLog;
_errNo = GET_SOCK_ERRNO;
return self;
}
- (void)dealloc
{
[_socket release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to listen in socket of type %@ with a back log of %d! "
ERRFMT, _inClass, _backLog, ERRPARAM];
return _description;
}
- (OFTCPSocket*)socket
{
OF_GETTER(_socket, NO)
}
- (int)backLog
{
return _backLog;
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFLockFailedException.h
from [188f78e407]
to [2b07e05b3e].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that locking a lock failed.
*/
@interface OFLockFailedException: OFException
{
id <OFLocking> lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that locking a lock failed.
*/
@interface OFLockFailedException: OFException
{
id <OFLocking> _lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFLockFailedException.m
from [1ba4665169]
to [71c95c97b9].
︙ | | | ︙ | |
18
19
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
|
#import "OFLockFailedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFLockFailedException
+ (instancetype)exceptionWithClass: (Class)class_
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class_
lock: lock] autorelease];
}
- initWithClass: (Class)class_
lock: (id <OFLocking>)lock_
{
self = [super initWithClass: class_];
lock = [lock_ retain];
return self;
}
- (void)dealloc
{
[lock release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"A lock of type %@ could not be locked in class %@!",
[(id)lock className], inClass];
return description;
}
- (id <OFLocking>)lock
{
OF_GETTER(lock, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#import "OFLockFailedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFLockFailedException
+ (instancetype)exceptionWithClass: (Class)class
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class
lock: lock] autorelease];
}
- initWithClass: (Class)class
lock: (id <OFLocking>)lock
{
self = [super initWithClass: class];
_lock = [lock retain];
return self;
}
- (void)dealloc
{
[_lock release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"A lock of type %@ could not be locked in class %@!",
[_lock class], _inClass];
return _description;
}
- (id <OFLocking>)lock
{
OF_GETTER(_lock, NO)
}
@end
|
Modified src/exceptions/OFMalformedXMLException.h
from [3ab544f3ad]
to [d4ce063be2].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFXMLParser;
/*!
* @brief An exception indicating that a parser encountered malformed XML.
*/
@interface OFMalformedXMLException: OFException
{
OFXMLParser *parser;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFXMLParser *parser;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFXMLParser;
/*!
* @brief An exception indicating that a parser encountered malformed XML.
*/
@interface OFMalformedXMLException: OFException
{
OFXMLParser *_parser;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFXMLParser *parser;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFMalformedXMLException.m
from [fdeb42d350]
to [92f13cee04].
︙ | | | ︙ | |
19
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
|
#import "OFMalformedXMLException.h"
#import "OFString.h"
#import "OFXMLParser.h"
#import "common.h"
@implementation OFMalformedXMLException
+ (instancetype)exceptionWithClass: (Class)class_
parser: (OFXMLParser*)parser
{
return [[[self alloc] initWithClass: class_
parser: parser] autorelease];
}
- initWithClass: (Class)class_
parser: (OFXMLParser*)parser_
{
self = [super initWithClass: class_];
parser = [parser_ retain];
return self;
}
- (void)dealloc
{
[parser release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
if (parser != nil)
description = [[OFString alloc] initWithFormat:
@"The parser in class %@ encountered malformed XML!",
inClass];
else
description = @"A parser encountered malformed XML!";
return description;
}
- (OFXMLParser*)parser
{
OF_GETTER(parser, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#import "OFMalformedXMLException.h"
#import "OFString.h"
#import "OFXMLParser.h"
#import "common.h"
@implementation OFMalformedXMLException
+ (instancetype)exceptionWithClass: (Class)class
parser: (OFXMLParser*)parser
{
return [[[self alloc] initWithClass: class
parser: parser] autorelease];
}
- initWithClass: (Class)class
parser: (OFXMLParser*)parser
{
self = [super initWithClass: class];
_parser = [parser retain];
return self;
}
- (void)dealloc
{
[_parser release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
if (_parser != nil)
_description = [[OFString alloc] initWithFormat:
@"The XML parser in class %@ encountered malformed XML!",
_inClass];
else
_description = @"An XML parser encountered malformed XML!";
return _description;
}
- (OFXMLParser*)parser
{
OF_GETTER(_parser, NO)
}
@end
|
Modified src/exceptions/OFMemoryNotPartOfObjectException.h
from [91de5ea6dc]
to [711c041b2a].
︙ | | | ︙ | |
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating the given memory is not part of the object.
*/
@interface OFMemoryNotPartOfObjectException: OFException
{
void *pointer;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *pointer;
#endif
/*!
* @brief Creates a new, autoreleased memory not part of object exception.
*
* @param class_ The class of the object which caused the exception
* @param ptr A pointer to the memory that is not part of the object
* @return A new, autoreleased memory not part of object exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
pointer: (void*)ptr;
/*!
* @brief Initializes an already allocated memory not part of object exception.
*
* @param class_ The class of the object which caused the exception
* @param ptr A pointer to the memory that is not part of the object
* @return An initialized memory not part of object exception
*/
- initWithClass: (Class)class_
pointer: (void*)ptr;
/*!
* @brief Returns a pointer to the memory which is not part of the object.
*
* @return A pointer to the memory which is not part of the object
*/
- (void*)pointer;
@end
|
|
|
|
|
|
|
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating the given memory is not part of the object.
*/
@interface OFMemoryNotPartOfObjectException: OFException
{
void *_pointer;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) void *pointer;
#endif
/*!
* @brief Creates a new, autoreleased memory not part of object exception.
*
* @param class_ The class of the object which caused the exception
* @param pointer A pointer to the memory that is not part of the object
* @return A new, autoreleased memory not part of object exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
pointer: (void*)pointer;
/*!
* @brief Initializes an already allocated memory not part of object exception.
*
* @param class_ The class of the object which caused the exception
* @param pointer A pointer to the memory that is not part of the object
* @return An initialized memory not part of object exception
*/
- initWithClass: (Class)class_
pointer: (void*)pointer;
/*!
* @brief Returns a pointer to the memory which is not part of the object.
*
* @return A pointer to the memory which is not part of the object
*/
- (void*)pointer;
@end
|
Modified src/exceptions/OFMemoryNotPartOfObjectException.m
from [a1452e1fb6]
to [b794b10a09].
︙ | | | ︙ | |
18
19
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
|
#include <stdlib.h>
#import "OFMemoryNotPartOfObjectException.h"
#import "OFString.h"
@implementation OFMemoryNotPartOfObjectException
+ (instancetype)exceptionWithClass: (Class)class_
pointer: (void*)ptr
{
return [[[self alloc] initWithClass: class_
pointer: ptr] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
pointer: (void*)ptr
{
self = [super initWithClass: class_];
pointer = ptr;
return self;
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Memory at %p was not allocated as part of object of class %@, "
@"thus the memory allocation was not changed! It is also possible "
@"that there was an attempt to free the same memory twice.",
pointer, inClass];
return description;
}
- (void*)pointer
{
return pointer;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#include <stdlib.h>
#import "OFMemoryNotPartOfObjectException.h"
#import "OFString.h"
@implementation OFMemoryNotPartOfObjectException
+ (instancetype)exceptionWithClass: (Class)class
pointer: (void*)pointer
{
return [[[self alloc] initWithClass: class
pointer: pointer] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
pointer: (void*)pointer
{
self = [super initWithClass: class];
_pointer = pointer;
return self;
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Memory at %p was not allocated as part of object of class %@, "
@"thus the memory allocation was not changed! It is also possible "
@"that there was an attempt to free the same memory twice.",
_pointer, _inClass];
return _description;
}
- (void*)pointer
{
return _pointer;
}
@end
|
Modified src/exceptions/OFNotConnectedException.h
from [1bd7530b03]
to [281c34dc5e].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFStreamSocket;
/*!
* @brief An exception indicating a socket is not connected or bound.
*/
@interface OFNotConnectedException: OFException
{
OFStreamSocket *socket;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStreamSocket *socket;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFStreamSocket;
/*!
* @brief An exception indicating a socket is not connected or bound.
*/
@interface OFNotConnectedException: OFException
{
OFStreamSocket *_socket;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStreamSocket *socket;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFNotConnectedException.m
from [96b427f88f]
to [202a3a6c5f].
︙ | | | ︙ | |
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
|
#import "OFNotConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFNotConnectedException
+ (instancetype)exceptionWithClass: (Class)class_
socket: (OFStreamSocket*)socket
{
return [[[self alloc] initWithClass: class_
socket: socket] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
socket: (OFStreamSocket*)socket_
{
self = [super initWithClass: class_];
socket = [socket_ retain];
return self;
}
- (void)dealloc
{
[socket release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The socket of type %@ is not connected or bound!", inClass];
return description;
}
- (OFStreamSocket*)socket
{
OF_GETTER(socket, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFNotConnectedException.h"
#import "OFString.h"
#import "OFTCPSocket.h"
#import "common.h"
@implementation OFNotConnectedException
+ (instancetype)exceptionWithClass: (Class)class
socket: (OFStreamSocket*)socket
{
return [[[self alloc] initWithClass: class
socket: socket] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
socket: (OFStreamSocket*)socket
{
self = [super initWithClass: class];
_socket = [socket retain];
return self;
}
- (void)dealloc
{
[_socket release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The socket of type %@ is not connected or bound!", _inClass];
return _description;
}
- (OFStreamSocket*)socket
{
OF_GETTER(_socket, NO)
}
@end
|
Modified src/exceptions/OFNotImplementedException.h
from [abb1f691d5]
to [0e5ad9eeda].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that a method or part of it is not
* implemented.
*/
@interface OFNotImplementedException: OFException
{
SEL selector;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that a method or part of it is not
* implemented.
*/
@interface OFNotImplementedException: OFException
{
SEL _selector;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) SEL selector;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFNotImplementedException.m
from [0a119c960d]
to [7dc7df3c42].
︙ | | | ︙ | |
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
|
#import "OFNotImplementedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFNotImplementedException
+ (instancetype)exceptionWithClass: (Class)class_
selector: (SEL)selector
{
return [[[self alloc] initWithClass: class_
selector: selector] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
selector: (SEL)selector_
{
self = [super initWithClass: class_];
selector = selector_;
return self;
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The selector %s is not understood by class %@ or not (fully) "
@"implemented!", sel_getName(selector), inClass];
return description;
}
- (SEL)selector
{
return selector;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFNotImplementedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFNotImplementedException
+ (instancetype)exceptionWithClass: (Class)class
selector: (SEL)selector
{
return [[[self alloc] initWithClass: class
selector: selector] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
selector: (SEL)selector
{
self = [super initWithClass: class];
_selector = selector;
return self;
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The selector %s is not understood by class %@ or not (fully) "
@"implemented!", sel_getName(_selector), _inClass];
return _description;
}
- (SEL)selector
{
return _selector;
}
@end
|
Modified src/exceptions/OFOpenFileFailedException.h
from [dd2d7a6ac4]
to [5b0e6f089a].
︙ | | | ︙ | |
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#import "OFException.h"
/*!
* @brief An exception indicating a file couldn't be opened.
*/
@interface OFOpenFileFailedException: OFException
{
OFString *path;
OFString *mode;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path;
@property (readonly, copy, nonatomic) OFString *mode;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased open file failed exception.
*
* @param class_ The class of the object which caused the exception
|
|
<
|
|
<
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#import "OFException.h"
/*!
* @brief An exception indicating a file couldn't be opened.
*/
@interface OFOpenFileFailedException: OFException
{
OFString *_path, *_mode;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *path, *mode;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased open file failed exception.
*
* @param class_ The class of the object which caused the exception
|
︙ | | | ︙ | |
Modified src/exceptions/OFOpenFileFailedException.m
from [2be3d5c462]
to [fd065f5f06].
︙ | | | ︙ | |
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
|
#import "OFOpenFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFOpenFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
path: (OFString*)path
mode: (OFString*)mode
{
return [[[self alloc] initWithClass: class_
path: path
mode: mode] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
path: (OFString*)path_
mode: (OFString*)mode_
{
self = [super initWithClass: class_];
@try {
path = [path_ copy];
mode = [mode_ copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[path release];
[mode release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to open file %@ with mode %@ in class %@! " ERRFMT, path,
mode, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)path
{
OF_GETTER(path, NO)
}
- (OFString*)mode
{
OF_GETTER(mode, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFOpenFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFOpenFileFailedException
+ (instancetype)exceptionWithClass: (Class)class
path: (OFString*)path
mode: (OFString*)mode
{
return [[[self alloc] initWithClass: class
path: path
mode: mode] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
path: (OFString*)path
mode: (OFString*)mode
{
self = [super initWithClass: class];
@try {
_path = [path copy];
_mode = [mode copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_path release];
[_mode release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to open file %@ with mode %@ in class %@! " ERRFMT, _path,
_mode, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)path
{
OF_GETTER(_path, NO)
}
- (OFString*)mode
{
OF_GETTER(_mode, NO)
}
@end
|
Modified src/exceptions/OFOutOfMemoryException.h
from [70140dd883]
to [fbe9775a49].
︙ | | | ︙ | |
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating there is not enough memory available.
*/
@interface OFOutOfMemoryException: OFException
{
size_t requestedSize;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t requestedSize;
#endif
/*!
* @brief Creates a new, autoreleased no memory exception.
*
* @param class_ The class of the object which caused the exception
* @param size The size of the memory that couldn't be allocated
* @return A new, autoreleased no memory exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
requestedSize: (size_t)size;
/*!
* @brief Initializes an already allocated no memory exception.
*
* @param class_ The class of the object which caused the exception
* @param size The size of the memory that couldn't be allocated
* @return An initialized no memory exception
*/
- initWithClass: (Class)class_
requestedSize: (size_t)size;
/*!
* @brief Returns the size of the memoory that couldn't be allocated.
*
* @return The size of the memoory that couldn't be allocated
*/
- (size_t)requestedSize;
@end
|
|
|
|
|
|
|
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating there is not enough memory available.
*/
@interface OFOutOfMemoryException: OFException
{
size_t _requestedSize;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t requestedSize;
#endif
/*!
* @brief Creates a new, autoreleased no memory exception.
*
* @param class_ The class of the object which caused the exception
* @param requestedSize The size of the memory that couldn't be allocated
* @return A new, autoreleased no memory exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
requestedSize: (size_t)requestedSize;
/*!
* @brief Initializes an already allocated no memory exception.
*
* @param class_ The class of the object which caused the exception
* @param requestedSize The size of the memory that couldn't be allocated
* @return An initialized no memory exception
*/
- initWithClass: (Class)class_
requestedSize: (size_t)requestedSize;
/*!
* @brief Returns the size of the memoory that couldn't be allocated.
*
* @return The size of the memoory that couldn't be allocated
*/
- (size_t)requestedSize;
@end
|
Modified src/exceptions/OFOutOfMemoryException.m
from [1897414e22]
to [632b122d6b].
︙ | | | ︙ | |
16
17
18
19
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
|
#include "config.h"
#import "OFOutOfMemoryException.h"
#import "OFString.h"
@implementation OFOutOfMemoryException
+ (instancetype)exceptionWithClass: (Class)class_
requestedSize: (size_t)size
{
return [[[self alloc] initWithClass: class_
requestedSize: size] autorelease];
}
- initWithClass: (Class)class_
requestedSize: (size_t)size
{
self = [super initWithClass: class_];
requestedSize = size;
return self;
}
- (OFString*)description
{
if (description != nil)
return description;
if (requestedSize != 0)
description = [[OFString alloc] initWithFormat:
@"Could not allocate %zu bytes in class %@!", requestedSize,
inClass];
else
description = [[OFString alloc] initWithFormat:
@"Could not allocate enough memory in class %@!", inClass];
return description;
}
- (size_t)requestedSize
{
return requestedSize;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16
17
18
19
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
|
#include "config.h"
#import "OFOutOfMemoryException.h"
#import "OFString.h"
@implementation OFOutOfMemoryException
+ (instancetype)exceptionWithClass: (Class)class
requestedSize: (size_t)requestedSize
{
return [[[self alloc] initWithClass: class
requestedSize: requestedSize] autorelease];
}
- initWithClass: (Class)class
requestedSize: (size_t)requestedSize
{
self = [super initWithClass: class];
_requestedSize = requestedSize;
return self;
}
- (OFString*)description
{
if (_description != nil)
return _description;
if (_requestedSize != 0)
_description = [[OFString alloc] initWithFormat:
@"Could not allocate %zu bytes in class %@!",
_requestedSize, _inClass];
else
_description = [[OFString alloc] initWithFormat:
@"Could not allocate enough memory in class %@!", _inClass];
return _description;
}
- (size_t)requestedSize
{
return _requestedSize;
}
@end
|
Modified src/exceptions/OFOutOfRangeException.m
from [ae918491aa]
to [adf5140fee].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFOutOfRangeException.h"
#import "OFString.h"
@implementation OFOutOfRangeException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Value out of range in class %@!", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#import "OFOutOfRangeException.h"
#import "OFString.h"
@implementation OFOutOfRangeException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Value out of range in class %@!", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFReadFailedException.m
from [7235b51172]
to [c76f9e9235].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#import "OFString.h"
#import "common.h"
@implementation OFReadFailedException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to read %zu bytes in class %@! " ERRFMT, requestedLength,
inClass, ERRPARAM];
return description;
}
@end
|
|
|
|
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#import "OFString.h"
#import "common.h"
@implementation OFReadFailedException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to read %zu bytes in class %@! " ERRFMT, _requestedLength,
_inClass, ERRPARAM];
return _description;
}
@end
|
Modified src/exceptions/OFReadOrWriteFailedException.h
from [578afdb049]
to [9ca5afb590].
︙ | | | ︙ | |
19
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
|
@class OFStream;
/*!
* @brief An exception indicating a read or write to a stream failed.
*/
@interface OFReadOrWriteFailedException: OFException
{
OFStream *stream;
size_t requestedLength;
@public
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
@property (readonly) size_t requestedLength;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased read or write failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream which caused the read or write failed exception
* @param length The requested length of the data that couldn't be read /
* written
* @return A new, autoreleased read or write failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
stream: (OFStream*)stream
requestedLength: (size_t)length;
/*!
* @brief Initializes an already allocated read or write failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream which caused the read or write failed exception
* @param length The requested length of the data that couldn't be read /
* written
* @return A new open file failed exception
*/
- initWithClass: (Class)class_
stream: (OFStream*)stream
requestedLength: (size_t)length;
/*!
* @brief Returns the stream which caused the read or write failed exception.
*
* @return The stream which caused the read or write failed exception
*/
- (OFStream*)stream;
|
|
|
|
|
|
|
|
|
|
|
19
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
|
@class OFStream;
/*!
* @brief An exception indicating a read or write to a stream failed.
*/
@interface OFReadOrWriteFailedException: OFException
{
OFStream *_stream;
size_t _requestedLength;
@public
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
@property (readonly) size_t requestedLength;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased read or write failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream which caused the read or write failed exception
* @param requestedLength The requested length of the data that couldn't be
* read / written
* @return A new, autoreleased read or write failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
stream: (OFStream*)stream
requestedLength: (size_t)requestedLength;
/*!
* @brief Initializes an already allocated read or write failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream which caused the read or write failed exception
* @param requestedLength The requested length of the data that couldn't be
* read / written
* @return A new open file failed exception
*/
- initWithClass: (Class)class_
stream: (OFStream*)stream
requestedLength: (size_t)requestedLength;
/*!
* @brief Returns the stream which caused the read or write failed exception.
*
* @return The stream which caused the read or write failed exception
*/
- (OFStream*)stream;
|
︙ | | | ︙ | |
Modified src/exceptions/OFReadOrWriteFailedException.m
from [9aff6467fd]
to [29e58b37e2].
︙ | | | ︙ | |
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
|
#import "OFReadOrWriteFailedException.h"
#import "OFString.h"
#import "OFStreamSocket.h"
#import "common.h"
@implementation OFReadOrWriteFailedException
+ (instancetype)exceptionWithClass: (Class)class_
stream: (OFStream*)stream
requestedLength: (size_t)length
{
return [[[self alloc] initWithClass: class_
stream: stream
requestedLength: length] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
stream: (OFStream*)stream_
requestedLength: (size_t)length
{
self = [super initWithClass: class_];
stream = [stream_ retain];
requestedLength = length;
if ([class_ isSubclassOfClass: [OFStreamSocket class]])
errNo = GET_SOCK_ERRNO;
else
errNo = GET_ERRNO;
return self;
}
- (void)dealloc
{
[stream release];
[super dealloc];
}
- (OFStream*)stream
{
OF_GETTER(stream, NO)
}
- (size_t)requestedLength
{
return requestedLength;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFReadOrWriteFailedException.h"
#import "OFString.h"
#import "OFStreamSocket.h"
#import "common.h"
@implementation OFReadOrWriteFailedException
+ (instancetype)exceptionWithClass: (Class)class
stream: (OFStream*)stream
requestedLength: (size_t)requestedLength
{
return [[[self alloc] initWithClass: class
stream: stream
requestedLength: requestedLength] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
stream: (OFStream*)stream
requestedLength: (size_t)requestedLength
{
self = [super initWithClass: class];
_stream = [stream retain];
_requestedLength = requestedLength;
if ([class isSubclassOfClass: [OFStreamSocket class]])
_errNo = GET_SOCK_ERRNO;
else
_errNo = GET_ERRNO;
return self;
}
- (void)dealloc
{
[_stream release];
[super dealloc];
}
- (OFStream*)stream
{
OF_GETTER(_stream, NO)
}
- (size_t)requestedLength
{
return _requestedLength;
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFRenameFileFailedException.h
from [fca6849bad]
to [0227ecc2e0].
︙ | | | ︙ | |
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating that renaming a file failed.
*/
@interface OFRenameFileFailedException: OFException
{
OFString *sourcePath;
OFString *destinationPath;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased rename file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The original path
* @param destination The new path
* @return A new, autoreleased rename file failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Initializes an already allocated rename failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The original path
* @param destination The new path
* @return An initialized rename file failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
<
|
|
|
<
|
|
|
|
|
|
|
|
|
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating that renaming a file failed.
*/
@interface OFRenameFileFailedException: OFException
{
OFString *_sourcePath, *_destinationPath;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased rename file failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The original path
* @param destinationPath The new path
* @return A new, autoreleased rename file failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Initializes an already allocated rename failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The original path
* @param destinationPath The new path
* @return An initialized rename file failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFRenameFileFailedException.m
from [985b1ab9ce]
to [300b802be6].
︙ | | | ︙ | |
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
|
#import "OFRenameFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFRenameFileFailedException
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
return [[[self alloc] initWithClass: class_
sourcePath: source
destinationPath: destination] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
self = [super initWithClass: class_];
@try {
sourcePath = [source copy];
destinationPath = [destination copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sourcePath release];
[destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to rename file %@ to %@ in class %@! " ERRFMT, sourcePath,
destinationPath, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(destinationPath, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFRenameFileFailedException.h"
#import "OFString.h"
#import "common.h"
@implementation OFRenameFileFailedException
+ (instancetype)exceptionWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
return [[[self alloc] initWithClass: class
sourcePath: sourcePath
destinationPath: destinationPath] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
self = [super initWithClass: class];
@try {
_sourcePath = [sourcePath copy];
_destinationPath = [destinationPath copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_sourcePath release];
[_destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to rename file %@ to %@ in class %@! " ERRFMT,
_sourcePath, _destinationPath, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(_sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(_destinationPath, NO)
}
@end
|
Modified src/exceptions/OFSeekFailedException.h
from [f8c1d060d7]
to [0430f3b8bb].
︙ | | | ︙ | |
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
|
@class OFSeekableStream;
/*!
* @brief An exception indicating that seeking in a stream failed.
*/
@interface OFSeekFailedException: OFException
{
OFSeekableStream *stream;
off_t offset;
int whence;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFSeekableStream *stream;
@property (readonly) off_t offset;
@property (readonly) int whence;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased seek failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream for which seeking failed
|
|
|
|
<
|
<
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
@class OFSeekableStream;
/*!
* @brief An exception indicating that seeking in a stream failed.
*/
@interface OFSeekFailedException: OFException
{
OFSeekableStream *_stream;
off_t _offset;
int _whence, _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFSeekableStream *stream;
@property (readonly) off_t offset;
@property (readonly) int whence, errNo;
#endif
/*!
* @brief Creates a new, autoreleased seek failed exception.
*
* @param class_ The class of the object which caused the exception
* @param stream The stream for which seeking failed
|
︙ | | | ︙ | |
Modified src/exceptions/OFSeekFailedException.m
from [817ab9cf57]
to [b267411948].
︙ | | | ︙ | |
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
|
#import "OFSeekFailedException.h"
#import "OFString.h"
#import "OFSeekableStream.h"
#import "common.h"
@implementation OFSeekFailedException
+ (instancetype)exceptionWithClass: (Class)class_
stream: (OFSeekableStream*)stream
offset: (off_t)offset
whence: (int)whence
{
return [[[self alloc] initWithClass: class_
stream: stream
offset: offset
whence: whence] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
stream: (OFSeekableStream*)stream_
offset: (off_t)offset_
whence: (int)whence_
{
self = [super initWithClass: class_];
stream = [stream_ retain];
offset = offset_;
whence = whence_;
errNo = GET_ERRNO;
return self;
}
- (void)dealloc
{
[stream release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Seeking failed in class %@! " ERRFMT, inClass, ERRPARAM];
return description;
}
- (OFSeekableStream*)stream
{
OF_GETTER(stream, NO)
}
- (off_t)offset
{
return offset;
}
- (int)whence
{
return whence;
}
- (int)errNo
{
return errNo;
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFSeekFailedException.h"
#import "OFString.h"
#import "OFSeekableStream.h"
#import "common.h"
@implementation OFSeekFailedException
+ (instancetype)exceptionWithClass: (Class)class
stream: (OFSeekableStream*)stream
offset: (off_t)offset
whence: (int)whence
{
return [[[self alloc] initWithClass: class
stream: stream
offset: offset
whence: whence] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
stream: (OFSeekableStream*)stream
offset: (off_t)offset
whence: (int)whence
{
self = [super initWithClass: class];
_stream = [stream retain];
_offset = offset;
_whence = whence;
_errNo = GET_ERRNO;
return self;
}
- (void)dealloc
{
[_stream release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Seeking failed in class %@! " ERRFMT, _inClass, ERRPARAM];
return _description;
}
- (OFSeekableStream*)stream
{
OF_GETTER(_stream, NO)
}
- (off_t)offset
{
return _offset;
}
- (int)whence
{
return _whence;
}
- (int)errNo
{
return _errNo;
}
@end
|
Modified src/exceptions/OFSetOptionFailedException.h
from [bd44868d64]
to [2d153af019].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFStream;
/*!
* @brief An exception indicating that setting an option for a stream failed.
*/
@interface OFSetOptionFailedException: OFException
{
OFStream *stream;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFStream;
/*!
* @brief An exception indicating that setting an option for a stream failed.
*/
@interface OFSetOptionFailedException: OFException
{
OFStream *_stream;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFStream *stream;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFSetOptionFailedException.m
from [e3ec9f7433]
to [440af04fa4].
︙ | | | ︙ | |
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
|
#import "OFSetOptionFailedException.h"
#import "OFString.h"
#import "OFStream.h"
#import "common.h"
@implementation OFSetOptionFailedException
+ (instancetype)exceptionWithClass: (Class)class_
stream: (OFStream*)stream
{
return [[[self alloc] initWithClass: class_
stream: stream] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
stream: (OFStream*)stream_
{
self = [super initWithClass: class_];
stream = [stream_ retain];
return self;
}
- (void)dealloc
{
[stream release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Setting an option in class %@ failed!", inClass];
return description;
}
- (OFStream*)stream
{
OF_GETTER(stream, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFSetOptionFailedException.h"
#import "OFString.h"
#import "OFStream.h"
#import "common.h"
@implementation OFSetOptionFailedException
+ (instancetype)exceptionWithClass: (Class)class
stream: (OFStream*)stream
{
return [[[self alloc] initWithClass: class
stream: stream] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
stream: (OFStream*)stream
{
self = [super initWithClass: class];
_stream = [stream retain];
return self;
}
- (void)dealloc
{
[_stream release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Setting an option in class %@ failed!", _inClass];
return _description;
}
- (OFStream*)stream
{
OF_GETTER(_stream, NO)
}
@end
|
Modified src/exceptions/OFStillLockedException.h
from [8fd0b0d990]
to [cb52dc053c].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that a lock is still locked.
*/
@interface OFStillLockedException: OFException
{
id <OFLocking> lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that a lock is still locked.
*/
@interface OFStillLockedException: OFException
{
id <OFLocking> _lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFStillLockedException.m
from [a5659659aa]
to [3a0467e9cd].
︙ | | | ︙ | |
18
19
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
|
#import "OFStillLockedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFStillLockedException
+ (instancetype)exceptionWithClass: (Class)class_
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class_
lock: lock] autorelease];
}
- initWithClass: (Class)class_
lock: (id <OFLocking>)lock_
{
self = [super initWithClass: class_];
lock = [lock_ retain];
return self;
}
- (void)dealloc
{
[lock release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Deallocation of a lock of type %@ was tried in class %@, even "
@"though it was still locked!", [(id)lock className], inClass];
return description;
}
- (id <OFLocking>)lock
{
OF_GETTER(lock, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#import "OFStillLockedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFStillLockedException
+ (instancetype)exceptionWithClass: (Class)class
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class
lock: lock] autorelease];
}
- initWithClass: (Class)class
lock: (id <OFLocking>)lock
{
self = [super initWithClass: class];
_lock = [lock retain];
return self;
}
- (void)dealloc
{
[_lock release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Deallocation of a lock of type %@ was tried in class %@, even "
@"though it was still locked!", [_lock class], _inClass];
return _description;
}
- (id <OFLocking>)lock
{
OF_GETTER(_lock, NO)
}
@end
|
Modified src/exceptions/OFSymlinkFailedException.h
from [946be7c3c1]
to [0ceec2f0f6].
︙ | | | ︙ | |
18
19
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
|
#ifndef _WIN32
/*!
* @brief An exception indicating that creating a symlink failed.
*/
@interface OFSymlinkFailedException: OFException
{
OFString *sourcePath;
OFString *destinationPath;
int errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath;
@property (readonly, copy, nonatomic) OFString *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased symlink failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The source for the symlink
* @param destination The destination for the symlink
* @return A new, autoreleased symlink failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Initializes an already allocated symlink failed exception.
*
* @param class_ The class of the object which caused the exception
* @param source The source for the symlink
* @param destination The destination for the symlink
* @return An initialized symlink failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
<
|
|
|
<
|
|
|
|
|
|
|
|
|
18
19
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
|
#ifndef _WIN32
/*!
* @brief An exception indicating that creating a symlink failed.
*/
@interface OFSymlinkFailedException: OFException
{
OFString *_sourcePath, *_destinationPath;
int _errNo;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *sourcePath, *destinationPath;
@property (readonly) int errNo;
#endif
/*!
* @brief Creates a new, autoreleased symlink failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The source for the symlink
* @param destinationPath The destination for the symlink
* @return A new, autoreleased symlink failed exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Initializes an already allocated symlink failed exception.
*
* @param class_ The class of the object which caused the exception
* @param sourcePath The source for the symlink
* @param destinationPath The destination for the symlink
* @return An initialized symlink failed exception
*/
- initWithClass: (Class)class_
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath;
/*!
* @brief Returns the errno from when the exception was created.
*
* @return The errno from when the exception was created
*/
- (int)errNo;
|
︙ | | | ︙ | |
Modified src/exceptions/OFSymlinkFailedException.m
from [2eea5d324c]
to [98d414e112].
︙ | | | ︙ | |
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
|
#import "OFSymlinkFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFSymlinkFailedException
+ (instancetype)exceptionWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
return [[[self alloc] initWithClass: class_
sourcePath: source
destinationPath: destination] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
sourcePath: (OFString*)source
destinationPath: (OFString*)destination
{
self = [super initWithClass: class_];
@try {
sourcePath = [source copy];
destinationPath = [destination copy];
errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[sourcePath release];
[destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to symlink file %@ to %@ in class %@! " ERRFMT, sourcePath,
destinationPath, inClass, ERRPARAM];
return description;
}
- (int)errNo
{
return errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(destinationPath, NO)
}
@end
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFSymlinkFailedException.h"
#import "OFString.h"
#import "common.h"
#ifndef _WIN32
@implementation OFSymlinkFailedException
+ (instancetype)exceptionWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
return [[[self alloc] initWithClass: class
sourcePath: sourcePath
destinationPath: destinationPath] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
sourcePath: (OFString*)sourcePath
destinationPath: (OFString*)destinationPath
{
self = [super initWithClass: class];
@try {
_sourcePath = [sourcePath copy];
_destinationPath = [destinationPath copy];
_errNo = GET_ERRNO;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_sourcePath release];
[_destinationPath release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to symlink file %@ to %@ in class %@! " ERRFMT,
_sourcePath, _destinationPath, _inClass, ERRPARAM];
return _description;
}
- (int)errNo
{
return _errNo;
}
- (OFString*)sourcePath
{
OF_GETTER(_sourcePath, NO)
}
- (OFString*)destinationPath
{
OF_GETTER(_destinationPath, NO)
}
@end
#endif
|
Modified src/exceptions/OFThreadJoinFailedException.h
from [2a2936121c]
to [8ae844634a].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that joining a thread failed.
*/
@interface OFThreadJoinFailedException: OFException
{
OFThread *thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that joining a thread failed.
*/
@interface OFThreadJoinFailedException: OFException
{
OFThread *_thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFThreadJoinFailedException.m
from [4dd632518d]
to [1398fa6a7a].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFThreadJoinFailedException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadJoinFailedException
+ (instancetype)exceptionWithClass: (Class)class_
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class_
thread: thread] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
thread: (OFThread*)thread_
{
self = [super initWithClass: class_];
thread = [thread_ retain];
return self;
}
- (void)dealloc
{
[thread release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Joining a thread of class %@ failed! Most likely, another thread "
@"already waits for the thread to join.", inClass];
return description;
}
- (OFThread*)thread
{
OF_GETTER(thread, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFThreadJoinFailedException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadJoinFailedException
+ (instancetype)exceptionWithClass: (Class)class
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class
thread: thread] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
thread: (OFThread*)thread
{
self = [super initWithClass: class];
_thread = [thread retain];
return self;
}
- (void)dealloc
{
[_thread release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Joining a thread of class %@ failed! Most likely, another thread "
@"already waits for the thread to join.", _inClass];
return _description;
}
- (OFThread*)thread
{
OF_GETTER(_thread, NO)
}
@end
|
Modified src/exceptions/OFThreadStartFailedException.h
from [f0826175fb]
to [b941a35e28].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that starting a thread failed.
*/
@interface OFThreadStartFailedException: OFException
{
OFThread *thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that starting a thread failed.
*/
@interface OFThreadStartFailedException: OFException
{
OFThread *_thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFThreadStartFailedException.m
from [dc9d7f84a8]
to [c4d2751745].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFThreadStartFailedException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadStartFailedException
+ (instancetype)exceptionWithClass: (Class)class_
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class_
thread: thread] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
thread: (OFThread*)thread_
{
self = [super initWithClass: class_];
thread = [thread_ retain];
return self;
}
- (void)dealloc
{
[thread release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Starting a thread of class %@ failed!", inClass];
return description;
}
- (OFThread*)thread
{
OF_GETTER(thread, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFThreadStartFailedException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadStartFailedException
+ (instancetype)exceptionWithClass: (Class)class
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class
thread: thread] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
thread: (OFThread*)thread
{
self = [super initWithClass: class];
_thread = [thread retain];
return self;
}
- (void)dealloc
{
[_thread release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Starting a thread of class %@ failed!", _inClass];
return _description;
}
- (OFThread*)thread
{
OF_GETTER(_thread, NO)
}
@end
|
Modified src/exceptions/OFThreadStillRunningException.h
from [d927ce5d9d]
to [405b10fbdf].
︙ | | | ︙ | |
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that a thread is still running.
*/
@interface OFThreadStillRunningException: OFException
{
OFThread *thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
|
|
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@class OFThread;
/*!
* @brief An exception indicating that a thread is still running.
*/
@interface OFThreadStillRunningException: OFException
{
OFThread *_thread;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFThread *thread;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFThreadStillRunningException.m
from [b0e805dcc0]
to [fb8e07d9a0].
︙ | | | ︙ | |
19
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
|
#include <stdlib.h>
#import "OFThreadStillRunningException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadStillRunningException
+ (instancetype)exceptionWithClass: (Class)class_
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class_
thread: thread] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
thread: (OFThread*)thread_
{
self = [super initWithClass: class_];
thread = [thread_ retain];
return self;
}
- (void)dealloc
{
[thread release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Deallocation of a thread of type %@ was tried, even though it "
@"was still running!", inClass];
return description;
}
- (OFThread*)thread
{
OF_GETTER(thread, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19
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
|
#include <stdlib.h>
#import "OFThreadStillRunningException.h"
#import "OFString.h"
#import "OFThread.h"
@implementation OFThreadStillRunningException
+ (instancetype)exceptionWithClass: (Class)class
thread: (OFThread*)thread
{
return [[[self alloc] initWithClass: class
thread: thread] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
thread: (OFThread*)thread
{
self = [super initWithClass: class];
_thread = [thread retain];
return self;
}
- (void)dealloc
{
[_thread release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Deallocation of a thread of type %@ was tried, even though it "
@"was still running!", _inClass];
return _description;
}
- (OFThread*)thread
{
OF_GETTER(_thread, NO)
}
@end
|
Modified src/exceptions/OFTruncatedDataException.m
from [c262fab980]
to [0c9b919885].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#import "OFTruncatedDataException.h"
#import "OFString.h"
@implementation OFTruncatedDataException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Truncated data was received or produced in class %@ while it "
@"should not have been truncated!", inClass];
return description;
}
@end
|
|
|
|
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#import "OFTruncatedDataException.h"
#import "OFString.h"
@implementation OFTruncatedDataException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Truncated data was received or produced in class %@ while it "
@"should not have been truncated!", _inClass];
return _description;
}
@end
|
Modified src/exceptions/OFUnboundNamespaceException.h
from [a52b906543]
to [39eed6d3dc].
︙ | | | ︙ | |
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating an attempt to use an unbound namespace.
*/
@interface OFUnboundNamespaceException: OFException
{
OFString *ns;
OFString *prefix;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic, getter=namespace) OFString *ns;
@property (readonly, copy, nonatomic) OFString *prefix;
#endif
/*!
* @brief Creates a new, autoreleased unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param ns The namespace which is unbound
* @return A new, autoreleased unbound namespace exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
namespace: (OFString*)ns;
/*!
* @brief Creates a new, autoreleased unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param prefix The prefix which is unbound
* @return A new, autoreleased unbound namespace exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
prefix: (OFString*)prefix;
/*!
* @brief Initializes an already allocated unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param ns The namespace which is unbound
* @return An initialized unbound namespace exception
*/
- initWithClass: (Class)class_
namespace: (OFString*)ns;
/*!
* @brief Initializes an already allocated unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param prefix The prefix which is unbound
* @return An initialized unbound namespace exception
|
|
<
<
|
|
|
|
|
|
17
18
19
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
|
#import "OFException.h"
/*!
* @brief An exception indicating an attempt to use an unbound namespace.
*/
@interface OFUnboundNamespaceException: OFException
{
OFString *_namespace, *_prefix;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *namespace, *prefix;
#endif
/*!
* @brief Creates a new, autoreleased unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param namespace The namespace which is unbound
* @return A new, autoreleased unbound namespace exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
namespace: (OFString*)namespace;
/*!
* @brief Creates a new, autoreleased unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param prefix The prefix which is unbound
* @return A new, autoreleased unbound namespace exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
prefix: (OFString*)prefix;
/*!
* @brief Initializes an already allocated unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param namespace The namespace which is unbound
* @return An initialized unbound namespace exception
*/
- initWithClass: (Class)class_
namespace: (OFString*)namespace;
/*!
* @brief Initializes an already allocated unbound namespace exception.
*
* @param class_ The class of the object which caused the exception
* @param prefix The prefix which is unbound
* @return An initialized unbound namespace exception
|
︙ | | | ︙ | |
Modified src/exceptions/OFUnboundNamespaceException.m
from [042719481e]
to [8482013ced].
︙ | | | ︙ | |
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
|
#import "OFUnboundNamespaceException.h"
#import "OFString.h"
#import "common.h"
@implementation OFUnboundNamespaceException
+ (instancetype)exceptionWithClass: (Class)class_
namespace: (OFString*)ns
{
return [[[self alloc] initWithClass: class_
namespace: ns] autorelease];
}
+ (instancetype)exceptionWithClass: (Class)class_
prefix: (OFString*)prefix
{
return [[[self alloc] initWithClass: class_
prefix: prefix] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
namespace: (OFString*)ns_
{
self = [super initWithClass: class_];
@try {
ns = [ns_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithClass: (Class)class_
prefix: (OFString*)prefix_
{
self = [super initWithClass: class_];
@try {
prefix = [prefix_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[ns release];
[prefix release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
if (ns != nil)
description = [[OFString alloc] initWithFormat:
@"The namespace %@ is not bound in class %@", ns, inClass];
else if (prefix != nil)
description = [[OFString alloc] initWithFormat:
@"The prefix %@ is not bound to any namespace in class %@",
prefix, inClass];
return description;
}
- (OFString*)namespace
{
OF_GETTER(ns, NO)
}
- (OFString*)prefix
{
OF_GETTER(prefix, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
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
|
#import "OFUnboundNamespaceException.h"
#import "OFString.h"
#import "common.h"
@implementation OFUnboundNamespaceException
+ (instancetype)exceptionWithClass: (Class)class
namespace: (OFString*)namespace
{
return [[[self alloc] initWithClass: class
namespace: namespace] autorelease];
}
+ (instancetype)exceptionWithClass: (Class)class
prefix: (OFString*)prefix
{
return [[[self alloc] initWithClass: class
prefix: prefix] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
namespace: (OFString*)namespace
{
self = [super initWithClass: class];
@try {
_namespace = [namespace copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- initWithClass: (Class)class
prefix: (OFString*)prefix
{
self = [super initWithClass: class];
@try {
_prefix = [prefix copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_namespace release];
[_prefix release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
if (_namespace != nil)
_description = [[OFString alloc] initWithFormat:
@"The namespace %@ is not bound in class %@", _namespace,
_inClass];
else if (_prefix != nil)
_description = [[OFString alloc] initWithFormat:
@"The prefix %@ is not bound to any namespace in class %@",
_prefix, _inClass];
return _description;
}
- (OFString*)namespace
{
OF_GETTER(_namespace, NO)
}
- (OFString*)prefix
{
OF_GETTER(_prefix, NO)
}
@end
|
Modified src/exceptions/OFUnlockFailedException.h
from [d78e1a213b]
to [0bb7635d95].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that unlocking a lock failed.
*/
@interface OFUnlockFailedException: OFException
{
id <OFLocking> lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#import "OFLocking.h"
/*!
* @brief An exception indicating that unlocking a lock failed.
*/
@interface OFUnlockFailedException: OFException
{
id <OFLocking> _lock;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) id <OFLocking> lock;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFUnlockFailedException.m
from [3a12901a60]
to [93c2224d43].
︙ | | | ︙ | |
18
19
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
|
#import "OFUnlockFailedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFUnlockFailedException
+ (instancetype)exceptionWithClass: (Class)class_
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class_
lock: lock] autorelease];
}
- initWithClass: (Class)class_
lock: (id <OFLocking>)lock_
{
self = [super initWithClass: class_];
lock = [lock_ retain];
return self;
}
- (void)dealloc
{
[lock release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"A lock of class %@ could not be unlocked in class %@!",
[(id)lock className], inClass];
return description;
}
- (id <OFLocking>)lock
{
OF_GETTER(lock, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18
19
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
|
#import "OFUnlockFailedException.h"
#import "OFString.h"
#import "macros.h"
@implementation OFUnlockFailedException
+ (instancetype)exceptionWithClass: (Class)class
lock: (id <OFLocking>)lock
{
return [[[self alloc] initWithClass: class
lock: lock] autorelease];
}
- initWithClass: (Class)class
lock: (id <OFLocking>)lock
{
self = [super initWithClass: class];
_lock = [lock retain];
return self;
}
- (void)dealloc
{
[_lock release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"A lock of class %@ could not be unlocked in class %@!",
[_lock class], _inClass];
return _description;
}
- (id <OFLocking>)lock
{
OF_GETTER(_lock, NO)
}
@end
|
Modified src/exceptions/OFUnsupportedProtocolException.h
from [8ebd174edb]
to [b626bac85b].
︙ | | | ︙ | |
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
|
/*!
* @brief An exception indicating that the protocol specified by the URL is not
* supported.
*/
@interface OFUnsupportedProtocolException: OFException
{
OFURL *URL;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFURL *URL;
#endif
/*!
* @brief Creates a new, autoreleased unsupported protocol exception.
*
* @param class_ The class of the object which caused the exception
* @param url The URL whose protocol is unsupported
* @return A new, autoreleased unsupported protocol exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
URL: (OFURL*)url;
/*!
* @brief Initializes an already allocated unsupported protocol exception
*
* @param class_ The class of the object which caused the exception
* @param url The URL whose protocol is unsupported
* @return An initialized unsupported protocol exception
*/
- initWithClass: (Class)class_
URL: (OFURL*)url;
/*!
* @brief Returns the URL whose protocol is unsupported.
*
* @return The URL whose protocol is unsupported
*/
- (OFURL*)URL;
@end
|
|
|
|
|
|
|
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
|
/*!
* @brief An exception indicating that the protocol specified by the URL is not
* supported.
*/
@interface OFUnsupportedProtocolException: OFException
{
OFURL *_URL;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, retain, nonatomic) OFURL *URL;
#endif
/*!
* @brief Creates a new, autoreleased unsupported protocol exception.
*
* @param class_ The class of the object which caused the exception
* @param URL The URL whose protocol is unsupported
* @return A new, autoreleased unsupported protocol exception
*/
+ (instancetype)exceptionWithClass: (Class)class_
URL: (OFURL*)URL;
/*!
* @brief Initializes an already allocated unsupported protocol exception
*
* @param class_ The class of the object which caused the exception
* @param URL The URL whose protocol is unsupported
* @return An initialized unsupported protocol exception
*/
- initWithClass: (Class)class_
URL: (OFURL*)URL;
/*!
* @brief Returns the URL whose protocol is unsupported.
*
* @return The URL whose protocol is unsupported
*/
- (OFURL*)URL;
@end
|
Modified src/exceptions/OFUnsupportedProtocolException.m
from [6a769966a7]
to [50dbd9a635].
︙ | | | ︙ | |
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
|
#import "OFUnsupportedProtocolException.h"
#import "OFString.h"
#import "OFURL.h"
#import "common.h"
@implementation OFUnsupportedProtocolException
+ (instancetype)exceptionWithClass: (Class)class_
URL: (OFURL*)url
{
return [[[self alloc] initWithClass: class_
URL: url] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
URL: (OFURL*)url
{
self = [super initWithClass: class_];
@try {
URL = [url copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[URL release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"The protocol of URL %@ is not supported by class %@", URL,
inClass];
return description;
}
- (OFURL*)URL
{
OF_GETTER(URL, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFUnsupportedProtocolException.h"
#import "OFString.h"
#import "OFURL.h"
#import "common.h"
@implementation OFUnsupportedProtocolException
+ (instancetype)exceptionWithClass: (Class)class
URL: (OFURL*)url
{
return [[[self alloc] initWithClass: class
URL: url] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
URL: (OFURL*)URL
{
self = [super initWithClass: class];
@try {
_URL = [URL copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_URL release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"The protocol of URL %@ is not supported by class %@", _URL,
_inClass];
return _description;
}
- (OFURL*)URL
{
OF_GETTER(_URL, NO)
}
@end
|
Modified src/exceptions/OFUnsupportedVersionException.h
from [4544e1d428]
to [d4879e4859].
︙ | | | ︙ | |
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that the specified version of the format or
* protocol is not supported.
*/
@interface OFUnsupportedVersionException: OFException
{
OFString *version;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *version;
#endif
/*!
|
|
|
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
/*!
* @brief An exception indicating that the specified version of the format or
* protocol is not supported.
*/
@interface OFUnsupportedVersionException: OFException
{
OFString *_version;
}
#ifdef OF_HAVE_PROPERTIES
@property (readonly, copy, nonatomic) OFString *version;
#endif
/*!
|
︙ | | | ︙ | |
Modified src/exceptions/OFUnsupportedVersionException.m
from [40aa737247]
to [23d60f6018].
︙ | | | ︙ | |
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
|
#import "OFUnsupportedVersionException.h"
#import "OFString.h"
#import "common.h"
@implementation OFUnsupportedVersionException
+ (instancetype)exceptionWithClass: (Class)class_
version: (OFString*)version
{
return [[[self alloc] initWithClass: class_
version: version] autorelease];
}
- initWithClass: (Class)class_
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class_
version: (OFString*)version_
{
self = [super initWithClass: class_];
@try {
version = [version_ copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[version release];
[super dealloc];
}
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Version %@ of the format or protocol is not supported by class "
@"%@", version, inClass];
return description;
}
- (OFString*)version
{
OF_GETTER(version, NO)
}
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
#import "OFUnsupportedVersionException.h"
#import "OFString.h"
#import "common.h"
@implementation OFUnsupportedVersionException
+ (instancetype)exceptionWithClass: (Class)class
version: (OFString*)version
{
return [[[self alloc] initWithClass: class
version: version] autorelease];
}
- initWithClass: (Class)class
{
@try {
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
}
- initWithClass: (Class)class
version: (OFString*)version
{
self = [super initWithClass: class];
@try {
_version = [version copy];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_version release];
[super dealloc];
}
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Version %@ of the format or protocol is not supported by class "
@"%@", _version, _inClass];
return _description;
}
- (OFString*)version
{
OF_GETTER(_version, NO)
}
@end
|
Modified src/exceptions/OFWriteFailedException.m
from [9862940d46]
to [659d063c26].
︙ | | | ︙ | |
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#import "OFString.h"
#import "common.h"
@implementation OFWriteFailedException
- (OFString*)description
{
if (description != nil)
return description;
description = [[OFString alloc] initWithFormat:
@"Failed to write %zu bytes in class %@! " ERRFMT, requestedLength,
inClass, ERRPARAM];
return description;
}
@end
|
|
|
|
|
|
|
|
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#import "OFString.h"
#import "common.h"
@implementation OFWriteFailedException
- (OFString*)description
{
if (_description != nil)
return _description;
_description = [[OFString alloc] initWithFormat:
@"Failed to write %zu bytes in class %@! " ERRFMT, _requestedLength,
_inClass, ERRPARAM];
return _description;
}
@end
|
Modified src/exceptions/common.h
from [9a8f628a9b]
to [258ae8e83b].
︙ | | | ︙ | |
15
16
17
18
19
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
|
*/
#include <string.h>
#import "macros.h"
#ifndef _WIN32
#if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
# include <netdb.h>
#endif
# include <errno.h>
# define GET_ERRNO errno
# ifndef HAVE_THREADSAFE_GETADDRINFO
# define GET_AT_ERRNO h_errno
# else
# define GET_AT_ERRNO errno
# endif
# define GET_SOCK_ERRNO errno
# define ERRFMT "Error string was: %s"
# define ERRPARAM strerror(errNo)
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
# define AT_ERRPARAM hstrerror(errNo)
# else
# define AT_ERRPARAM strerror(errNo)
# endif
#else
# include <windows.h>
# define GET_ERRNO GetLastError()
# define GET_AT_ERRNO WSAGetLastError()
# define GET_SOCK_ERRNO WSAGetLastError()
# define ERRFMT "Error code was: %d"
# define ERRPARAM errNo
# define AT_ERRPARAM errNo
#endif
|
|
|
|
|
|
|
|
|
|
15
16
17
18
19
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
|
*/
#include <string.h>
#import "macros.h"
#ifndef _WIN32
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
# include <netdb.h>
# endif
# include <errno.h>
# define GET_ERRNO errno
# ifndef HAVE_THREADSAFE_GETADDRINFO
# define GET_AT_ERRNO h_errno
# else
# define GET_AT_ERRNO errno
# endif
# define GET_SOCK_ERRNO errno
# define ERRFMT "Error string was: %s"
# define ERRPARAM strerror(_errNo)
# if !defined(HAVE_THREADSAFE_GETADDRINFO) && !defined(_PSP)
# define AT_ERRPARAM hstrerror(_errNo)
# else
# define AT_ERRPARAM strerror(_errNo)
# endif
#else
# include <windows.h>
# define GET_ERRNO GetLastError()
# define GET_AT_ERRNO WSAGetLastError()
# define GET_SOCK_ERRNO WSAGetLastError()
# define ERRFMT "Error code was: %d"
# define ERRPARAM _errNo
# define AT_ERRPARAM _errNo
#endif
|
Modified tests/TestsAppDelegate.h
from [7bc108d8f9]
to [d5a4c58861].
︙ | | | ︙ | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
\
if (cond) \
[self outputSuccess: test \
inModule: module]; \
else { \
[self outputFailure: test \
inModule: module]; \
fails++; \
} \
}
#define EXPECT_EXCEPTION(test, exception, code) \
{ \
BOOL caught = NO; \
\
[self outputTesting: test \
|
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
\
if (cond) \
[self outputSuccess: test \
inModule: module]; \
else { \
[self outputFailure: test \
inModule: module]; \
_fails++; \
} \
}
#define EXPECT_EXCEPTION(test, exception, code) \
{ \
BOOL caught = NO; \
\
[self outputTesting: test \
|
︙ | | | ︙ | |
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
\
if (caught) \
[self outputSuccess: test \
inModule: module]; \
else { \
[self outputFailure: test \
inModule: module]; \
fails++; \
} \
}
#define R(x) (x, 1)
@class OFString;
@interface TestsAppDelegate: OFObject
{
int fails;
}
- (void)outputString: (OFString*)str
withColor: (int)color;
- (void)outputTesting: (OFString*)test
inModule: (OFString*)module;
- (void)outputSuccess: (OFString*)test
|
|
|
|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
\
if (caught) \
[self outputSuccess: test \
inModule: module]; \
else { \
[self outputFailure: test \
inModule: module]; \
_fails++; \
} \
}
#define R(x) (x, 1)
@class OFString;
@interface TestsAppDelegate: OFObject
{
int _fails;
}
- (void)outputString: (OFString*)str
withColor: (int)color;
- (void)outputTesting: (OFString*)test
inModule: (OFString*)module;
- (void)outputSuccess: (OFString*)test
|
︙ | | | ︙ | |
Modified tests/TestsAppDelegate.m
from [573b357575]
to [07d163fa23].
︙ | | | ︙ | |
152
153
154
155
156
157
158
159
160
161
|
[self pluginTests];
#endif
[self forwardingTests];
#ifdef OF_HAVE_PROPERTIES
[self propertiesTests];
#endif
[OFApplication terminateWithStatus: fails];
}
@end
|
|
|
152
153
154
155
156
157
158
159
160
161
|
[self pluginTests];
#endif
[self forwardingTests];
#ifdef OF_HAVE_PROPERTIES
[self propertiesTests];
#endif
[OFApplication terminateWithStatus: _fails];
}
@end
|