ObjFW  Diff

Differences From Artifact [468bf23684]:

To Artifact [b7faec4dac]:


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
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







+









+
















-
+
-
-
-

-
-
-
-
-
-
-
-





-
+
-
-
-




+
-
+





-
+






-
+







#include <limits.h>
#include <time.h>
#include <math.h>

#include <sys/time.h>

#import "OFDate.h"
#import "OFConcreteDate.h"
#import "OFData.h"
#import "OFDictionary.h"
#import "OFMessagePackExtension.h"
#ifdef OF_HAVE_THREADS
# import "OFMutex.h"
#endif
#import "OFStrPTime.h"
#import "OFString.h"
#import "OFSystemInfo.h"
#import "OFTaggedPointerDate.h"
#import "OFXMLAttribute.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#if defined(OF_AMIGAOS_M68K) || defined(OF_MINT)
/* amiga-gcc and freemint-gcc do not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif

@interface OFPlaceholderDate: OFDate
@end

@interface OFConcreteDate: OFDate
@interface OFConcreteDateSingleton: OFConcreteDate
{
	OFTimeInterval _seconds;
}
@end

@interface OFDateSingleton: OFConcreteDate
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@interface OFTaggedPointerDate: OFDateSingleton
@end
#endif

static struct {
	Class isa;
} placeholder;

static OFDateSingleton *zeroDate, *distantFuture, *distantPast;
static OFConcreteDateSingleton *zeroDate, *distantFuture, *distantPast;
#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
static int dateTag;
#endif

static void
initZeroDate(void)
{
	zeroDate = [[OFConcreteDateSingleton alloc]
	zeroDate = [[OFDateSingleton alloc] initWithTimeIntervalSince1970: 0];
	    initWithTimeIntervalSince1970: 0];
}

static void
initDistantFuture(void)
{
	distantFuture = [[OFDateSingleton alloc]
	distantFuture = [[OFConcreteDateSingleton alloc]
	    initWithTimeIntervalSince1970: 64060588800.0];
}

static void
initDistantPast(void)
{
	distantPast = [[OFDateSingleton alloc]
	distantPast = [[OFConcreteDateSingleton alloc]
	    initWithTimeIntervalSince1970: -62167219200.0];
}

static OFTimeInterval
now(void)
{
	struct timeval tv;
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260







-
+







	seconds += tm->tm_sec;
	/* Time zone */
	seconds += -(double)tz * 60;

	return seconds;
}

@implementation OFDateSingleton
@implementation OFConcreteDateSingleton
OF_SINGLETON_METHODS
@end

@implementation OFPlaceholderDate
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
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
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







-
-
+
+
















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	value = OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble(
	    seconds)));

	/* Almost all dates fall into this range. */
	if (value & (UINT64_C(4) << 60)) {
		id ret = objc_createTaggedPointer(dateTag,
		    value & ~(UINT64_C(4) << 60));
		id ret = [OFTaggedPointerDate
		    dateWithUInt64TimeIntervalSince1970: value];

		if (ret != nil)
			return ret;
	}
#endif

	return (id)[[OFConcreteDate alloc]
	    initWithTimeIntervalSince1970: seconds];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif

OF_SINGLETON_METHODS
@end

@implementation OFConcreteDate
- (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds
{
	self = [super initWithTimeIntervalSince1970: seconds];

	_seconds = seconds;

	return self;
}

- (OFTimeInterval)timeIntervalSince1970
{
	return _seconds;
}
@end

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
@implementation OFTaggedPointerDate
- (OFTimeInterval)timeIntervalSince1970
{
	uint64_t value = (uint64_t)object_getTaggedPointerValue(self);

	value |= UINT64_C(4) << 60;

	return OFFromBigEndianDouble(OFRawUInt64ToDouble(OFToBigEndian64(
	    value)));
}
@end
#endif

@implementation OFDate
+ (void)initialize
{
#ifdef OF_WINDOWS
	HMODULE module;
#endif
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
317
318
319
320
321
322
323




324
325
326
327
328
329
330







-
-
-
-







#endif

#ifdef OF_WINDOWS
	if ((module = LoadLibrary("msvcrt.dll")) != NULL)
		_mktime64FuncPtr = (__time64_t (*)(struct tm *))
		    GetProcAddress(module, "_mktime64");
#endif

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	dateTag = objc_registerTaggedPointerClass([OFTaggedPointerDate class]);
#endif
}

+ (instancetype)alloc
{
	if (self == [OFDate class])
		return (id)&placeholder;