LOTKeypath.m 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // LOTKeypath.m
  3. // Lottie_iOS
  4. //
  5. // Created by brandon_withrow on 12/13/17.
  6. // Copyright © 2017 Airbnb. All rights reserved.
  7. //
  8. #import "LOTKeypath.h"
  9. NSString *const kLOTKeypathEnd = @"LOTENDKEYPATH";
  10. @implementation LOTKeypath {
  11. NSInteger _currentDepth;
  12. NSMutableArray<NSNumber *> *_fuzzyDepthStack;
  13. NSMutableArray *_currentStack;
  14. NSArray *_keys;
  15. NSMutableDictionary *_searchResults;
  16. }
  17. + (nonnull LOTKeypath *)keypathWithString:(nonnull NSString *)keypath {
  18. return [[self alloc] initWithKeys:[keypath componentsSeparatedByString:@"."]];
  19. }
  20. + (nonnull LOTKeypath *)keypathWithKeys:(nonnull NSString *)firstKey, ... {
  21. NSMutableArray *keys = [NSMutableArray array];
  22. va_list args;
  23. va_start(args, firstKey);
  24. for (NSString *arg = firstKey; arg != nil; arg = va_arg(args, NSString*))
  25. {
  26. [keys addObject:arg];
  27. }
  28. va_end(args);
  29. return [[self alloc] initWithKeys:keys];
  30. }
  31. - (instancetype)initWithKeys:(NSArray *)keys {
  32. self = [super init];
  33. if (self) {
  34. _keys = [NSArray arrayWithArray:keys];
  35. NSMutableString *absolutePath = [NSMutableString string];
  36. for (int i = 0; i < _keys.count; i++) {
  37. if (i > 0) {
  38. [absolutePath appendString:@"."];
  39. }
  40. [absolutePath appendString:_keys[i]];
  41. }
  42. _currentStack = [NSMutableArray array];
  43. _absoluteKeypath = absolutePath;
  44. _currentDepth = 0;
  45. _fuzzyDepthStack = [NSMutableArray array];
  46. _searchResults = [NSMutableDictionary dictionary];
  47. }
  48. return self;
  49. }
  50. - (BOOL)pushKey:(nonnull NSString *)key {
  51. if (_currentDepth == _keys.count &&
  52. self.hasFuzzyWildcard == NO) {
  53. return NO;
  54. }
  55. NSString *current = self.currentKey;
  56. if (self.hasWildcard ||
  57. [current isEqualToString:key]) {
  58. [_currentStack addObject:[key copy]];
  59. _currentDepth ++;
  60. if (self.hasFuzzyWildcard) {
  61. [_fuzzyDepthStack addObject:@(_currentDepth)];
  62. }
  63. return YES;
  64. } else if (self.hasFuzzyWildcard) {
  65. [_currentStack addObject:[key copy]];
  66. return YES;
  67. }
  68. return NO;
  69. }
  70. - (void)popKey {
  71. if (_currentDepth == 0) {
  72. return;
  73. }
  74. NSInteger stackCount = _currentStack.count;
  75. [_currentStack removeLastObject];
  76. if (self.hasFuzzyWildcard ) {
  77. if (stackCount == _fuzzyDepthStack.lastObject.integerValue) {
  78. [_fuzzyDepthStack removeLastObject];
  79. } else {
  80. return;
  81. }
  82. }
  83. _currentDepth --;
  84. }
  85. - (void)popToRootKey {
  86. _currentDepth = 0;
  87. [_currentStack removeAllObjects];
  88. [_fuzzyDepthStack removeAllObjects];
  89. }
  90. - (NSString *)currentKey {
  91. if (_currentDepth == _keys.count) {
  92. return kLOTKeypathEnd;
  93. }
  94. return _keys[_currentDepth];
  95. }
  96. - (NSString *)currentKeyPath {
  97. return [_currentStack componentsJoinedByString:@"."];
  98. }
  99. - (BOOL)hasWildcard {
  100. if (_currentDepth == _keys.count) {
  101. return NO;
  102. }
  103. return ([_keys[_currentDepth] isEqualToString:@"**"] ||
  104. [_keys[_currentDepth] isEqualToString:@"*"]);
  105. }
  106. - (BOOL)hasFuzzyWildcard {
  107. if (_currentDepth == 0 ||
  108. _currentDepth > _keys.count) {
  109. return NO;
  110. }
  111. return [_keys[_currentDepth - 1] isEqualToString:@"**"];
  112. }
  113. - (BOOL)endOfKeypath {
  114. return (_currentDepth == _keys.count);
  115. }
  116. - (void)addSearchResultForCurrentPath:(id _Nonnull)result {
  117. [_searchResults setObject:result forKey:self.currentKeyPath];
  118. }
  119. - (NSDictionary *)searchResults {
  120. return _searchResults;
  121. }
  122. @end