LOTKeypath.m
3.3 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
//
// LOTKeypath.m
// Lottie_iOS
//
// Created by brandon_withrow on 12/13/17.
// Copyright © 2017 Airbnb. All rights reserved.
//
#import "LOTKeypath.h"
NSString *const kLOTKeypathEnd = @"LOTENDKEYPATH";
@implementation LOTKeypath {
NSInteger _currentDepth;
NSMutableArray<NSNumber *> *_fuzzyDepthStack;
NSMutableArray *_currentStack;
NSArray *_keys;
NSMutableDictionary *_searchResults;
}
+ (nonnull LOTKeypath *)keypathWithString:(nonnull NSString *)keypath {
return [[self alloc] initWithKeys:[keypath componentsSeparatedByString:@"."]];
}
+ (nonnull LOTKeypath *)keypathWithKeys:(nonnull NSString *)firstKey, ... {
NSMutableArray *keys = [NSMutableArray array];
va_list args;
va_start(args, firstKey);
for (NSString *arg = firstKey; arg != nil; arg = va_arg(args, NSString*))
{
[keys addObject:arg];
}
va_end(args);
return [[self alloc] initWithKeys:keys];
}
- (instancetype)initWithKeys:(NSArray *)keys {
self = [super init];
if (self) {
_keys = [NSArray arrayWithArray:keys];
NSMutableString *absolutePath = [NSMutableString string];
for (int i = 0; i < _keys.count; i++) {
if (i > 0) {
[absolutePath appendString:@"."];
}
[absolutePath appendString:_keys[i]];
}
_currentStack = [NSMutableArray array];
_absoluteKeypath = absolutePath;
_currentDepth = 0;
_fuzzyDepthStack = [NSMutableArray array];
_searchResults = [NSMutableDictionary dictionary];
}
return self;
}
- (BOOL)pushKey:(nonnull NSString *)key {
if (_currentDepth == _keys.count &&
self.hasFuzzyWildcard == NO) {
return NO;
}
NSString *current = self.currentKey;
if (self.hasWildcard ||
[current isEqualToString:key]) {
[_currentStack addObject:[key copy]];
_currentDepth ++;
if (self.hasFuzzyWildcard) {
[_fuzzyDepthStack addObject:@(_currentDepth)];
}
return YES;
} else if (self.hasFuzzyWildcard) {
[_currentStack addObject:[key copy]];
return YES;
}
return NO;
}
- (void)popKey {
if (_currentDepth == 0) {
return;
}
NSInteger stackCount = _currentStack.count;
[_currentStack removeLastObject];
if (self.hasFuzzyWildcard ) {
if (stackCount == _fuzzyDepthStack.lastObject.integerValue) {
[_fuzzyDepthStack removeLastObject];
} else {
return;
}
}
_currentDepth --;
}
- (void)popToRootKey {
_currentDepth = 0;
[_currentStack removeAllObjects];
[_fuzzyDepthStack removeAllObjects];
}
- (NSString *)currentKey {
if (_currentDepth == _keys.count) {
return kLOTKeypathEnd;
}
return _keys[_currentDepth];
}
- (NSString *)currentKeyPath {
return [_currentStack componentsJoinedByString:@"."];
}
- (BOOL)hasWildcard {
if (_currentDepth == _keys.count) {
return NO;
}
return ([_keys[_currentDepth] isEqualToString:@"**"] ||
[_keys[_currentDepth] isEqualToString:@"*"]);
}
- (BOOL)hasFuzzyWildcard {
if (_currentDepth == 0 ||
_currentDepth > _keys.count) {
return NO;
}
return [_keys[_currentDepth - 1] isEqualToString:@"**"];
}
- (BOOL)endOfKeypath {
return (_currentDepth == _keys.count);
}
- (void)addSearchResultForCurrentPath:(id _Nonnull)result {
[_searchResults setObject:result forKey:self.currentKeyPath];
}
- (NSDictionary *)searchResults {
return _searchResults;
}
@end