ObjFW  Check-in [ad37db9133]

Overview
Comment:OFDate: Use tagged pointers
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tagged-pointers
Files: files | file ages | folders
SHA3-256: ad37db913316b9ca2dd21c51772c63f90252fd1d1a9496ac3a73bea87d6debe0
User & Date: js on 2020-07-25 16:22:17
Other Links: branch diff | manifest | tags
Context
2020-07-25
17:24
OFDate: Fix missing #ifdef check-in: 096c2662d6 user: js tags: tagged-pointers
16:22
OFDate: Use tagged pointers check-in: ad37db9133 user: js tags: tagged-pointers
14:17
OFDate: Add a designated initializer check-in: 33a133cda0 user: js tags: tagged-pointers
Changes

Modified src/OFDate.m from [7bc28080b9] to [bec84a8a1e].

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 "OFString.h"
#import "OFSystemInfo.h"
#import "OFXMLElement.h"

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

#import "OFOutOfRangeException.h"

#import "of_strptime.h"

#ifdef OF_AMIGAOS_M68K
/* amiga-gcc does not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif

@interface OFDate ()
+ (instancetype)of_alloc;
@end

@interface OFDateSingleton: OFDate
@end

@interface OFDatePlaceholder: OFDateSingleton
@end






static struct {
	Class isa;
} placeholder;

static OFDateSingleton *distantFuture, *distantPast;








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







>


















>
>
>
>
>





|
>
>
>
>
>
>
>







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 "OFString.h"
#import "OFSystemInfo.h"
#import "OFXMLElement.h"

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

#import "of_strptime.h"

#ifdef OF_AMIGAOS_M68K
/* amiga-gcc does not have trunc() */
# define trunc(x) ((int64_t)(x))
#endif

@interface OFDate ()
+ (instancetype)of_alloc;
@end

@interface OFDateSingleton: OFDate
@end

@interface OFDatePlaceholder: OFDateSingleton
@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 int dateTag;

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

static void
initDistantFuture(void)
{
	distantFuture = [[OFDateSingleton alloc]
	    initWithTimeIntervalSince1970: 64060588800.0];
}
266
267
268
269
270
271
272
























273
274
275
276
277
278














279
280
281
282
283
284
285
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds
{
























	return (id)[[OFDate of_alloc] initWithTimeIntervalSince1970: seconds];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif
@end















@implementation OFDate
+ (void)initialize
{
#ifdef OF_WINDOWS
	HMODULE module;
#endif







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






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







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
#ifdef __clang__
/* We intentionally don't call into super, so silence the warning. */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wobjc-designated-initializers"
#endif
- (instancetype)initWithTimeIntervalSince1970: (of_time_interval_t)seconds
{
#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	uint64_t value;
#endif

	if (seconds == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initZeroDate);
		return (id)zeroDate;
	}

#if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX
	value = OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE(
	    seconds)));

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

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

	return (id)[[OFDate of_alloc] initWithTimeIntervalSince1970: seconds];
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif
@end

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

	value |= UINT64_C(4) << 60;

	return OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
	    value)));
}
@end
#endif

@implementation OFDate
+ (void)initialize
{
#ifdef OF_WINDOWS
	HMODULE module;
#endif
295
296
297
298
299
300
301




302
303
304
305
306
307
308
#endif

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




}

+ (instancetype)of_alloc
{
	return [super alloc];
}








>
>
>
>







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#endif

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

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

+ (instancetype)of_alloc
{
	return [super alloc];
}

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
}

- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

	element = [OFXMLElement elementWithName: self.className
				      namespace: OF_SERIALIZATION_NS];

	element.stringValue = [OFString stringWithFormat: @"%016" PRIx64,
	    OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE(
	    self.timeIntervalSince1970)))];

	[element retain];







|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
}

- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *element;

	element = [OFXMLElement elementWithName: @"OFDate"
				      namespace: OF_SERIALIZATION_NS];

	element.stringValue = [OFString stringWithFormat: @"%016" PRIx64,
	    OF_BSWAP64_IF_LE(OF_DOUBLE_TO_INT_RAW(OF_BSWAP_DOUBLE_IF_LE(
	    self.timeIntervalSince1970)))];

	[element retain];
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
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];


	buffer = [self allocMemoryWithSize: pageSize];

	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else
		if (wcsftime(buffer, pageSize / sizeof(wchar_t),
		    format.UTF16String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF16String: buffer];
#endif
	} @finally {
		[self freeMemory: buffer];
	}

	return ret;
}

- (OFString *)localDateStringWithFormat: (OFConstantString *)format
{







>
>
|















|







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
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];
	if ((buffer = malloc(pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];

	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else
		if (wcsftime(buffer, pageSize / sizeof(wchar_t),
		    format.UTF16String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF16String: buffer];
#endif
	} @finally {
		free(buffer);
	}

	return ret;
}

- (OFString *)localDateStringWithFormat: (OFConstantString *)format
{
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
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];


	buffer = [self allocMemoryWithSize: pageSize];

	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else
		if (wcsftime(buffer, pageSize / sizeof(wchar_t),
		    format.UTF16String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF16String: buffer];
#endif
	} @finally {
		[self freeMemory: buffer];
	}

	return ret;
}

- (OFDate *)earlierDate: (OFDate *)otherDate
{







>
>
|















|







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
	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];
	if ((buffer = malloc(pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];

	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else
		if (wcsftime(buffer, pageSize / sizeof(wchar_t),
		    format.UTF16String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF16String: buffer];
#endif
	} @finally {
		free(buffer);
	}

	return ret;
}

- (OFDate *)earlierDate: (OFDate *)otherDate
{