forked from realm/realm-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RLMObjectId.mm
128 lines (109 loc) · 4.04 KB
/
RLMObjectId.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2020 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
#import "RLMObjectId_Private.hpp"
#import "RLMUtil.hpp"
#import <realm/object_id.hpp>
// Swift's obj-c bridging does not support making an obj-c defined class conform
// to Decodable, so we need a Swift-defined subclass for that. This means that
// when Realm Swift is being used, we need to produce objects of that type rather
// than our obj-c defined type. objc_runtime_visible marks the type as being
// visbile only to the obj-c runtime and not the linker, which means that it'll
// be `nil` at runtime rather than being a linker error if it's not defined, and
// valid if it happens to be defined by some other library (i.e. Realm Swift).
//
// At the point where the objects are being allocated we generally don't have
// any good way of knowing whether or not it's going to end up being used by
// Swift, so we just switch to the subclass unconditionally if the subclass
// exists. This shouldn't have any impact on obj-c code other than a small
// performance hit.
[[clang::objc_runtime_visible]]
@interface RealmSwiftObjectId : RLMObjectId
@end
@implementation RLMObjectId
- (instancetype)init {
if ((self = [super init])) {
if (auto cls = [RealmSwiftObjectId class]; cls && cls != self.class) {
object_setClass(self, cls);
}
}
return self;
}
- (instancetype)initWithString:(NSString *)string error:(NSError **)error {
if ((self = [self init])) {
const char *str = string.UTF8String;
if (!realm::ObjectId::is_valid_str(str)) {
if (error) {
NSString *msg = [NSString stringWithFormat:@"Invalid Object ID string '%@': must be 24 hex digits", string];
*error = [NSError errorWithDomain:RLMErrorDomain
code:RLMErrorInvalidInput
userInfo:@{NSLocalizedDescriptionKey: msg}];
}
return nil;
}
_value = realm::ObjectId(str);
}
return self;
}
- (instancetype)initWithTimestamp:(NSDate *)timestamp
machineIdentifier:(int)machineIdentifier
processIdentifier:(int)processIdentifier {
if ((self = [self init])) {
_value = realm::ObjectId(RLMTimestampForNSDate(timestamp), machineIdentifier, processIdentifier);
}
return self;
}
- (instancetype)initWithValue:(realm::ObjectId)value {
if ((self = [self init])) {
_value = value;
}
return self;
}
+ (instancetype)objectId {
return [[RLMObjectId alloc] initWithValue:realm::ObjectId::gen()];
}
- (BOOL)isEqual:(id)object {
if (RLMObjectId *objectId = RLMDynamicCast<RLMObjectId>(object)) {
return objectId->_value == _value;
}
return NO;
}
- (BOOL)isGreaterThan:(nullable RLMObjectId *)objectId {
return _value > objectId.value;
}
- (BOOL)isGreaterThanOrEqualTo:(nullable RLMObjectId *)objectId {
return _value >= objectId.value;
}
- (BOOL)isLessThan:(nullable RLMObjectId *)objectId {
return _value < objectId.value;
}
- (BOOL)isLessThanOrEqualTo:(nullable RLMObjectId *)objectId {
return _value <= objectId.value;
}
- (NSUInteger)hash {
return _value.hash();
}
- (NSString *)description {
return self.stringValue;
}
- (NSString *)stringValue {
return @(_value.to_string().c_str());
}
- (NSDate *)timestamp {
return RLMTimestampToNSDate(_value.get_timestamp());
}
@end