/Fluidium/lib/ParseKit/src/PKAssembly.m

https://github.com/ziz/fluidium · Objective C · 231 lines · 159 code · 57 blank · 15 comment · 23 complexity · 472c7807ccdf437fc845f81bb42d1e68 MD5 · raw file

  1. // Copyright 2010 Todd Ditchendorf
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import <ParseKit/PKAssembly.h>
  15. static NSString * const PKAssemblyDefaultDelimiter = @"/";
  16. @interface PKAssembly ()
  17. - (id)peek;
  18. - (id)next;
  19. - (BOOL)hasMore;
  20. - (NSString *)consumedObjectsJoinedByString:(NSString *)delimiter;
  21. - (NSString *)remainingObjectsJoinedByString:(NSString *)delimiter;
  22. @property (nonatomic, readwrite, retain) NSMutableArray *stack;
  23. @property (nonatomic) NSUInteger index;
  24. @property (nonatomic, retain) NSString *string;
  25. @property (nonatomic, readwrite, retain) NSString *defaultDelimiter;
  26. @property (nonatomic, readonly) NSUInteger length;
  27. @property (nonatomic, readonly) NSUInteger objectsConsumed;
  28. @property (nonatomic, readonly) NSUInteger objectsRemaining;
  29. @end
  30. @implementation PKAssembly
  31. + (PKAssembly *)assemblyWithString:(NSString *)s {
  32. return [[[self alloc] initWithString:s] autorelease];
  33. }
  34. - (id)init {
  35. return [self initWithString:nil];
  36. }
  37. - (id)initWithString:(NSString *)s {
  38. if (self = [super init]) {
  39. self.stack = [NSMutableArray array];
  40. self.string = s;
  41. }
  42. return self;
  43. }
  44. - (void)dealloc {
  45. self.stack = nil;
  46. self.string = nil;
  47. self.target = nil;
  48. self.defaultDelimiter = nil;
  49. [super dealloc];
  50. }
  51. - (id)copyWithZone:(NSZone *)zone {
  52. // use of NSAllocateObject() below is a *massive* optimization over calling the designated initializer -initWithString: here.
  53. // this line (and this method in general) is *vital* to the overall performance of the framework. dont fuck with it.
  54. PKAssembly *a = NSAllocateObject([self class], 0, zone);
  55. a->stack = [stack mutableCopyWithZone:zone];
  56. a->string = [string retain];
  57. if (defaultDelimiter) {
  58. a->defaultDelimiter = [defaultDelimiter retain];
  59. } else {
  60. a->defaultDelimiter = nil;
  61. }
  62. if (target) {
  63. if ([target conformsToProtocol:@protocol(NSMutableCopying)]) {
  64. a->target = [target mutableCopyWithZone:zone];
  65. } else {
  66. a->target = [target copyWithZone:zone];
  67. }
  68. } else {
  69. a->target = nil;
  70. }
  71. a->index = index;
  72. return a;
  73. }
  74. - (BOOL)isEqual:(id)obj {
  75. if (![obj isMemberOfClass:[self class]]) {
  76. return NO;
  77. }
  78. PKAssembly *a = (PKAssembly *)obj;
  79. if ([a length] != [self length]) {
  80. return NO;
  81. }
  82. if (a->index != index) {
  83. return NO;
  84. }
  85. if ([a.stack count] != [stack count]) {
  86. return NO;
  87. }
  88. return [[self description] isEqualToString:[obj description]];
  89. }
  90. - (id)next {
  91. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  92. return nil;
  93. }
  94. - (BOOL)hasMore {
  95. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  96. return NO;
  97. }
  98. - (NSString *)consumedObjectsJoinedByString:(NSString *)delimiter {
  99. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  100. return nil;
  101. }
  102. - (NSString *)remainingObjectsJoinedByString:(NSString *)delimiter {
  103. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  104. return nil;
  105. }
  106. - (NSUInteger)length {
  107. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  108. return 0;
  109. }
  110. - (NSUInteger)objectsConsumed {
  111. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  112. return 0;
  113. }
  114. - (NSUInteger)objectsRemaining {
  115. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  116. return 0;
  117. }
  118. - (id)peek {
  119. NSAssert1(0, @"-[PKAssembly %s] must be overriden", _cmd);
  120. return nil;
  121. }
  122. - (id)pop {
  123. id result = nil;
  124. if (![self isStackEmpty]) {
  125. result = [[[stack lastObject] retain] autorelease];
  126. [stack removeLastObject];
  127. }
  128. return result;
  129. }
  130. - (void)push:(id)object {
  131. if (object) {
  132. [stack addObject:object];
  133. }
  134. }
  135. - (BOOL)isStackEmpty {
  136. return 0 == [stack count];
  137. }
  138. - (NSArray *)objectsAbove:(id)fence {
  139. NSMutableArray *result = [NSMutableArray array];
  140. while (![self isStackEmpty]) {
  141. id obj = [self pop];
  142. if ([obj isEqual:fence]) {
  143. [self push:obj];
  144. break;
  145. } else {
  146. [result addObject:obj];
  147. }
  148. }
  149. return result;
  150. }
  151. - (NSString *)description {
  152. NSMutableString *s = [NSMutableString string];
  153. [s appendString:@"["];
  154. NSUInteger i = 0;
  155. NSUInteger len = [stack count];
  156. for (id obj in stack) {
  157. [s appendString:[obj description]];
  158. if (len - 1 != i++) {
  159. [s appendString:@", "];
  160. }
  161. }
  162. [s appendString:@"]"];
  163. NSString *d = defaultDelimiter ? defaultDelimiter : PKAssemblyDefaultDelimiter;
  164. [s appendString:[self consumedObjectsJoinedByString:d]];
  165. [s appendString:@"^"];
  166. [s appendString:[self remainingObjectsJoinedByString:d]];
  167. return [[s copy] autorelease];
  168. }
  169. @synthesize stack;
  170. @synthesize target;
  171. @synthesize index;
  172. @synthesize string;
  173. @synthesize defaultDelimiter;
  174. @end