5 // Created by Richard Murphy on 1/29/15.
9 #include "SOSGenCount.h"
10 #include <utilities/SecCFWrappers.h>
11 #include <CoreFoundation/CFLocale.h>
13 static CFAbsoluteTime
SOSGenerationCountGetDateBits(int64_t genValue
) {
14 return (uint32_t) ((((uint64_t) genValue
) >> 32) << 1);
17 void SOSGenerationCountWithDescription(SOSGenCountRef gen
, void (^operation
)(CFStringRef description
)) {
18 CFStringRef description
= SOSGenerationCountCopyDescription(gen
);
20 operation(description
);
22 CFReleaseSafe(description
);
25 CFStringRef
SOSGenerationCountCopyDescription(SOSGenCountRef gen
) {
26 int64_t value
= SOSGetGenerationSint(gen
);
28 CFMutableStringRef gcDecsription
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, CFSTR("["));
30 withStringOfAbsoluteTime(SOSGenerationCountGetDateBits(value
), ^(CFStringRef decription
) {
31 CFStringAppend(gcDecsription
, decription
);
34 CFStringAppendFormat(gcDecsription
, NULL
, CFSTR(" %u]"), (uint32_t)(value
& 0xFFFFFFFF));
39 int64_t SOSGetGenerationSint(SOSGenCountRef gen
) {
42 CFNumberGetValue(gen
, kCFNumberSInt64Type
, &value
);
46 static int64_t sosGenerationSetHighBits(int64_t value
, int32_t high_31
)
48 value
&= 0xFFFFFFFF; // Keep the low 32 bits.
49 value
|= ((int64_t) high_31
) << 32;
54 static SOSGenCountRef
sosGenerationCreateOrIncrement(SOSGenCountRef gen
) {
58 value
= SOSGetGenerationSint(gen
);
61 if((value
>> 32) == 0) {
62 uint32_t seconds
= CFAbsoluteTimeGetCurrent(); // seconds
63 value
= sosGenerationSetHighBits(value
, (seconds
>> 1));
67 return CFNumberCreate(NULL
, kCFNumberSInt64Type
, &value
);
70 SOSGenCountRef
SOSGenerationCreate() {
71 return sosGenerationCreateOrIncrement(NULL
);
74 SOSGenCountRef
SOSGenerationIncrementAndCreate(SOSGenCountRef gen
) {
75 return sosGenerationCreateOrIncrement(gen
);
78 SOSGenCountRef
SOSGenerationCopy(SOSGenCountRef gen
) {
80 int64_t value
= SOSGetGenerationSint(gen
);
81 return CFNumberCreate(NULL
, kCFNumberSInt64Type
, &value
);
84 bool SOSGenerationIsOlder(SOSGenCountRef current
, SOSGenCountRef proposed
) {
85 return CFNumberCompare(current
, proposed
, NULL
) == kCFCompareGreaterThan
;