nano-store 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/{CHANGELOG → CHANGELOG.md} +7 -0
  2. data/README.md +5 -1
  3. data/Rakefile +1 -1
  4. data/lib/nano_store.rb +1 -1
  5. data/lib/nano_store/finder.rb +10 -2
  6. data/lib/nano_store/model.rb +7 -7
  7. data/lib/nano_store/version.rb +1 -1
  8. data/spec/association_spec.rb +6 -6
  9. data/spec/finder_spec.rb +2 -0
  10. data/spec/model_spec.rb +33 -3
  11. data/spec/nano_store_spec.rb +5 -0
  12. data/spec/spec_helper.rb +14 -0
  13. data/vendor/Podfile.lock +3 -3
  14. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoBag.h +6 -1
  15. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine.h +5 -0
  16. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine_Private.h +2 -0
  17. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression.h +6 -0
  18. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression_Private.h +1 -1
  19. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals.h +5 -1
  20. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals_Private.h +6 -2
  21. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject.h +15 -3
  22. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject_Private.h +4 -0
  23. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoPredicate.h +6 -1
  24. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoResult.h +5 -0
  25. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSearch.h +16 -2
  26. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSortDescriptor.h +7 -1
  27. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore.h +12 -0
  28. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore_Private.h +3 -1
  29. data/vendor/Pods/BuildHeaders/NanoStore/NSFOrderedDictionary.h +33 -0
  30. data/vendor/Pods/BuildHeaders/NanoStore/NanoStore.h +36 -0
  31. data/vendor/Pods/Headers/NanoStore/NSFNanoBag.h +6 -1
  32. data/vendor/Pods/Headers/NanoStore/NSFNanoEngine.h +5 -0
  33. data/vendor/Pods/Headers/NanoStore/NSFNanoEngine_Private.h +2 -0
  34. data/vendor/Pods/Headers/NanoStore/NSFNanoExpression.h +6 -0
  35. data/vendor/Pods/Headers/NanoStore/NSFNanoExpression_Private.h +1 -1
  36. data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals.h +5 -1
  37. data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals_Private.h +6 -2
  38. data/vendor/Pods/Headers/NanoStore/NSFNanoObject.h +15 -3
  39. data/vendor/Pods/Headers/NanoStore/NSFNanoObject_Private.h +4 -0
  40. data/vendor/Pods/Headers/NanoStore/NSFNanoPredicate.h +6 -1
  41. data/vendor/Pods/Headers/NanoStore/NSFNanoResult.h +5 -0
  42. data/vendor/Pods/Headers/NanoStore/NSFNanoSearch.h +16 -2
  43. data/vendor/Pods/Headers/NanoStore/NSFNanoSortDescriptor.h +7 -1
  44. data/vendor/Pods/Headers/NanoStore/NSFNanoStore.h +12 -0
  45. data/vendor/Pods/Headers/NanoStore/NSFNanoStore_Private.h +3 -1
  46. data/vendor/Pods/Headers/NanoStore/NSFOrderedDictionary.h +33 -0
  47. data/vendor/Pods/Headers/NanoStore/NanoStore.h +36 -0
  48. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.h +5 -0
  49. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.m +142 -131
  50. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.h +5 -0
  51. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.m +148 -51
  52. data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.h +33 -0
  53. data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.m +148 -0
  54. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoEngine_Private.h +2 -0
  55. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoExpression_Private.h +1 -1
  56. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoGlobals_Private.h +6 -2
  57. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoObject_Private.h +4 -0
  58. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoStore_Private.h +3 -1
  59. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.h +6 -1
  60. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.m +126 -117
  61. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.h +6 -0
  62. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.m +32 -18
  63. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.h +5 -1
  64. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.m +6 -3
  65. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.h +15 -3
  66. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.m +152 -31
  67. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.h +6 -1
  68. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.m +51 -26
  69. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.h +16 -2
  70. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.m +156 -115
  71. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +7 -1
  72. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +34 -17
  73. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.h +12 -0
  74. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.m +210 -196
  75. data/vendor/Pods/NanoStore/Classes/Public/NanoStore.h +36 -0
  76. data/vendor/Pods/NanoStore/README.md +49 -0
  77. data/vendor/Pods/Pods.bridgesupport +798 -685
  78. metadata +30 -8
@@ -132,6 +132,11 @@
132
132
 
133
133
  - (NSString *)description;
134
134
 
135
+ /** Returns a JSON representation of the result.
136
+ */
137
+
138
+ - (NSString *)JSONDescription;
139
+
135
140
  //@}
136
141
 
137
142
  @end
@@ -27,16 +27,17 @@
27
27
  #import "NSFNanoResult.h"
28
28
  #import "NanoStore_Private.h"
29
29
 
30
- @implementation NSFNanoResult
31
- {
32
- @protected
33
- /** \cond */
34
- NSDictionary *results;
35
- /** \endcond */
36
- }
30
+ @interface NSFNanoResult ()
31
+
32
+ /** \cond */
33
+ @property (nonatomic, assign, readwrite) NSUInteger numberOfRows;
34
+ @property (nonatomic, strong, readwrite) NSError *error;
35
+ @property (nonatomic) NSDictionary *results;
36
+ /** \endcond */
37
37
 
38
- @synthesize numberOfRows;
39
- @synthesize error;
38
+ @end
39
+
40
+ @implementation NSFNanoResult
40
41
 
41
42
  /** \cond */
42
43
 
@@ -57,24 +58,24 @@
57
58
 
58
59
  - (NSString *)description
59
60
  {
60
- NSUInteger numberOfColumns = [[results allKeys]count];
61
+ NSUInteger numberOfColumns = [[_results allKeys]count];
61
62
 
62
63
  NSMutableString *description = [NSMutableString string];
63
64
  [description appendString:@"\n"];
64
- [description appendString:[NSString stringWithFormat:@"Result address : 0x%x\n", self]];
65
+ [description appendString:[NSString stringWithFormat:@"Result address : %p\n", self]];
65
66
  [description appendString:[NSString stringWithFormat:@"Number of columns : %ld\n", numberOfColumns]];
66
- if (nil == error)
67
+ if (nil == _error)
67
68
  if ([[self columns]count] > 0)
68
69
  [description appendString:[NSString stringWithFormat:@"Columns : %@\n", [[self columns]componentsJoinedByString:@", "]]];
69
70
  else
70
71
  [description appendString:[NSString stringWithFormat:@"Columns : %@\n", @"()"]];
71
72
  else
72
73
  [description appendString:[NSString stringWithFormat:@"Columns : %@\n", @"<column info not available>"]];
73
- [description appendString:[NSString stringWithFormat:@"Number of rows : %ld\n", numberOfRows]];
74
- if (nil == error)
74
+ [description appendString:[NSString stringWithFormat:@"Number of rows : %ld\n", _numberOfRows]];
75
+ if (nil == _error)
75
76
  [description appendString:[NSString stringWithFormat:@"Error : %@\n", @"<no error>"]];
76
77
  else
77
- [description appendString:[NSString stringWithFormat:@"Error : %@\n", [error localizedDescription]]];
78
+ [description appendString:[NSString stringWithFormat:@"Error : %@\n", [_error localizedDescription]]];
78
79
 
79
80
  // Print up to the first ten rows to help visualize the cursor
80
81
  if (0 != numberOfColumns) {
@@ -105,11 +106,11 @@
105
106
  }
106
107
 
107
108
  // Print the preview of the contents
108
- if (numberOfRows > 0) {
109
- NSInteger numberOfRowsToPrint = numberOfRows;
109
+ if (_numberOfRows > 0) {
110
+ NSInteger numberOfRowsToPrint = _numberOfRows;
110
111
  NSUInteger j;
111
112
 
112
- if (numberOfRows > 100) {
113
+ if (_numberOfRows > 100) {
113
114
  numberOfRowsToPrint = 100;
114
115
  }
115
116
 
@@ -118,7 +119,7 @@
118
119
  for (j = 0; j < numberOfColumns; j++) {
119
120
  NSString *columnName = [columns objectAtIndex:j];
120
121
  const char *value = "<plist data> ";
121
- if (NO == [columnName hasSuffix:@"NSFPlist"]) {
122
+ if (NO == [columnName hasSuffix:@"NSFKeyedArchive"]) {
122
123
  value = [[self valueAtIndex:i forColumn:columnName]UTF8String];
123
124
  }
124
125
 
@@ -139,21 +140,129 @@
139
140
  return description;
140
141
  }
141
142
 
143
+ - (NSFOrderedDictionary *)dictionaryDescription
144
+ {
145
+ NSUInteger numberOfColumns = [[_results allKeys]count];
146
+
147
+ NSFOrderedDictionary *values = [NSFOrderedDictionary new];
148
+
149
+ values[@"Result address"] = [NSString stringWithFormat:@"%p", self];
150
+ values[@"Number of columns"] = @(numberOfColumns);
151
+ if (nil == _error) {
152
+ if ([[self columns]count] > 0) {
153
+ values[@"Columns"] = [[self columns]componentsJoinedByString:@", "];
154
+ } else {
155
+ values[@"Columns"] = @"()";
156
+ }
157
+ } else {
158
+ values[@"Columns"] = @"<column info not available>";
159
+ }
160
+ values[@"Number of rows"] = @(_numberOfRows);
161
+ if (nil == _error) {
162
+ values[@"Error"] = @"<nil>";
163
+ } else {
164
+ values[@"Error"] = [NSString stringWithFormat:@"%@", [_error localizedDescription]];
165
+ }
166
+
167
+ // Print up to the first ten rows to help visualize the cursor
168
+ if (0 != numberOfColumns) {
169
+ NSUInteger i;
170
+ NSArray *columns = [self columns];
171
+ NSMutableString *contentString = [NSMutableString new];
172
+ NSMutableArray *printedContent = [NSMutableArray new];
173
+
174
+ // Print the names of the columns
175
+ [contentString appendString:[NSString stringWithFormat:@"%-15@ | ", @"Row # "]];
176
+ for (i = 0; i < numberOfColumns; i++) {
177
+ const char *value = [[columns objectAtIndex:i]UTF8String];
178
+ if (numberOfColumns - 1 > i) {
179
+ [contentString appendString:[NSString stringWithFormat:@"%-15s | ", value]];
180
+ } else {
181
+ [contentString appendString:[NSString stringWithFormat:@"%-15s", value]];
182
+ }
183
+ }
184
+ [printedContent addObject:[contentString copy]];
185
+
186
+ // Print the underline
187
+ [contentString setString:@""];
188
+ const char *value = "===============";
189
+ [contentString appendString:[NSString stringWithFormat:@"%-15s | ", value]];
190
+ for (i = 0; i < numberOfColumns; i++) {
191
+ if (numberOfColumns - 1 > i) {
192
+ [contentString appendString:[NSString stringWithFormat:@"%-15s | ", value]];
193
+ } else {
194
+ [contentString appendString:[NSString stringWithFormat:@"%-15s", value]];
195
+ }
196
+ }
197
+ [printedContent addObject:[contentString copy]];
198
+
199
+ // Print the preview of the contents
200
+ if (_numberOfRows > 0) {
201
+ NSInteger numberOfRowsToPrint = _numberOfRows;
202
+ NSUInteger j;
203
+
204
+ if (_numberOfRows > 100) {
205
+ numberOfRowsToPrint = 100;
206
+ }
207
+
208
+ [contentString setString:@""];
209
+
210
+ for (i = 0; i < numberOfRowsToPrint; i++) {
211
+ [contentString appendString:[NSString stringWithFormat:@"%-15ld | ", i]];
212
+ for (j = 0; j < numberOfColumns; j++) {
213
+ NSString *columnName = [columns objectAtIndex:j];
214
+ const char *value = "<plist data> ";
215
+ if (NO == [columnName hasSuffix:@"NSFPlist"]) {
216
+ value = [[self valueAtIndex:i forColumn:columnName]UTF8String];
217
+ }
218
+
219
+ if (numberOfColumns - 1 > j) {
220
+ [contentString appendString:[NSString stringWithFormat:@"%-15s | ", value]];
221
+ } else {
222
+ [contentString appendString:[NSString stringWithFormat:@"%-15s", value]];
223
+ }
224
+ }
225
+
226
+ [printedContent addObject:[contentString copy]];
227
+ }
228
+ } else {
229
+ [printedContent addObject:@"<no data available>"];
230
+ }
231
+
232
+ values[@"Preview of contents"] = printedContent;
233
+ }
234
+
235
+ return values;
236
+ }
237
+
238
+ - (NSString *)JSONDescription
239
+ {
240
+ NSFOrderedDictionary *values = [self dictionaryDescription];
241
+
242
+ NSError *outError = nil;
243
+ NSString *description = [NSFNanoObject _NSObjectToJSONString:values error:&outError];
244
+ if (nil != outError) {
245
+ description = [outError localizedDescription];
246
+ }
247
+
248
+ return description;
249
+ }
250
+
142
251
  #pragma mark -
143
252
 
144
253
  - (NSArray *)columns
145
254
  {
146
- return [results allKeys];
255
+ return [_results allKeys];
147
256
  }
148
257
 
149
258
  - (NSString *)valueAtIndex:(NSUInteger)index forColumn:(NSString *)column
150
259
  {
151
- return [[results objectForKey:column]objectAtIndex:index];
260
+ return [[_results objectForKey:column]objectAtIndex:index];
152
261
  }
153
262
 
154
263
  - (NSArray *)valuesForColumn:(NSString *)column
155
264
  {
156
- NSArray *values = [results objectForKey:column];
265
+ NSArray *values = [_results objectForKey:column];
157
266
 
158
267
  if (nil == values)
159
268
  values = [NSArray array];
@@ -163,22 +272,17 @@
163
272
 
164
273
  - (NSString *)firstValue
165
274
  {
166
- NSArray *columns = [results allKeys];
167
- if (([columns count] > 0) && (numberOfRows > 0)) {
168
- return [[results objectForKey:[columns objectAtIndex:0]]objectAtIndex:0];
275
+ NSArray *columns = [_results allKeys];
276
+ if (([columns count] > 0) && (_numberOfRows > 0)) {
277
+ return [[_results objectForKey:[columns objectAtIndex:0]]objectAtIndex:0];
169
278
  }
170
279
 
171
280
  return nil;
172
281
  }
173
282
 
174
- - (NSError *)error
175
- {
176
- return [error copy];
177
- }
178
-
179
283
  - (void)writeToFile:(NSString *)path;
180
284
  {
181
- [results writeToFile:[path stringByExpandingTildeInPath] atomically:YES];
285
+ [_results writeToFile:[path stringByExpandingTildeInPath] atomically:YES];
182
286
  }
183
287
 
184
288
  #pragma mark - Private Methods
@@ -199,16 +303,16 @@
199
303
  {
200
304
  if (nil == theResults)
201
305
  [[NSException exceptionWithName:NSFUnexpectedParameterException
202
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: theResults is nil.", [self class], _cmd]
306
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: theResults is nil.", [self class], NSStringFromSelector(_cmd)]
203
307
  userInfo:nil]raise];
204
308
 
205
309
  if ([theResults respondsToSelector:@selector(objectForKey:)] == NO)
206
310
  [[NSException exceptionWithName:NSFUnexpectedParameterException
207
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: theResults is not of type NSDictionary.", [self class], _cmd]
311
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: theResults is not of type NSDictionary.", [self class], NSStringFromSelector(_cmd)]
208
312
  userInfo:nil]raise];
209
313
 
210
314
  if ((self = [self init])) {
211
- results = theResults;
315
+ _results = theResults;
212
316
  [self _calculateNumberOfRows];
213
317
  }
214
318
 
@@ -219,45 +323,38 @@
219
323
  {
220
324
  if (nil == theError)
221
325
  [[NSException exceptionWithName:NSFUnexpectedParameterException
222
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: theError is nil.", [self class], _cmd]
326
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: theError is nil.", [self class], NSStringFromSelector(_cmd)]
223
327
  userInfo:nil]raise];
224
328
 
225
329
  if ([theError respondsToSelector:@selector(localizedDescription)] == NO)
226
330
  [[NSException exceptionWithName:NSFUnexpectedParameterException
227
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: theError is not of type NSError.", [self class], _cmd]
331
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: theError is not of type NSError.", [self class], NSStringFromSelector(_cmd)]
228
332
  userInfo:nil]raise];
229
333
 
230
334
  if ((self = [self init])) {
231
- error = theError;
335
+ _error = theError;
232
336
  [self _calculateNumberOfRows];
233
337
  }
234
338
 
235
339
  return self;
236
340
  }
237
341
 
238
- - (void)_setError:(NSError *)theError
239
- {
240
- if (error != theError) {
241
- error = theError;
242
- }
243
- }
244
-
245
342
  - (void)_reset
246
343
  {
247
- numberOfRows = -1;
248
- results = nil;
249
- error = nil;
344
+ _numberOfRows = -1;
345
+ _results = nil;
346
+ _error = nil;
250
347
  }
251
348
 
252
349
  - (void)_calculateNumberOfRows
253
350
  {
254
351
  // We cache the value once, for performance reasons
255
- if (-1 == numberOfRows) {
256
- NSArray *allKeys = [results allKeys];
352
+ if (-1 == _numberOfRows) {
353
+ NSArray *allKeys = [_results allKeys];
257
354
  if ([allKeys count] == 0)
258
- numberOfRows = 0;
355
+ _numberOfRows = 0;
259
356
  else
260
- numberOfRows = [[results objectForKey:[allKeys lastObject]]count];
357
+ _numberOfRows = [[_results objectForKey:[allKeys lastObject]]count];
261
358
  }
262
359
  }
263
360
  /** \endcond */
@@ -0,0 +1,33 @@
1
+ //
2
+ // NSFOrderedDictionary.h
3
+ // OrderedDictionary
4
+ //
5
+ // Created by Matt Gallagher on 19/12/08.
6
+ // Copyright 2008 Matt Gallagher. All rights reserved.
7
+ //
8
+ // v2 - ARC-compliant (Tito Ciuro)
9
+ // v1 - Initial release (Matt Gallagher)
10
+ //
11
+ // This software is provided 'as-is', without any express or implied
12
+ // warranty. In no event will the authors be held liable for any damages
13
+ // arising from the use of this software. Permission is granted to anyone to
14
+ // use this software for any purpose, including commercial applications, and to
15
+ // alter it and redistribute it freely, subject to the following restrictions:
16
+ //
17
+ // 1. The origin of this software must not be misrepresented; you must not
18
+ // claim that you wrote the original software. If you use this software
19
+ // in a product, an acknowledgment in the product documentation would be
20
+ // appreciated but is not required.
21
+ // 2. Altered source versions must be plainly marked as such, and must not be
22
+ // misrepresented as being the original software.
23
+ // 3. This notice may not be removed or altered from any source
24
+ // distribution.
25
+ //
26
+
27
+ @interface NSFOrderedDictionary : NSMutableDictionary
28
+
29
+ - (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
30
+ - (id)keyAtIndex:(NSUInteger)anIndex;
31
+ - (NSEnumerator *)reverseKeyEnumerator;
32
+
33
+ @end
@@ -0,0 +1,148 @@
1
+ //
2
+ // NSFOrderedDictionary.m
3
+ // OrderedDictionary
4
+ //
5
+ // Created by Matt Gallagher on 19/12/08.
6
+ // Copyright 2008 Matt Gallagher. All rights reserved.
7
+ //
8
+ // v2 - ARC-compliant (Tito Ciuro)
9
+ // v1 - Initial release (Matt Gallagher)
10
+ //
11
+ // This software is provided 'as-is', without any express or implied
12
+ // warranty. In no event will the authors be held liable for any damages
13
+ // arising from the use of this software. Permission is granted to anyone to
14
+ // use this software for any purpose, including commercial applications, and to
15
+ // alter it and redistribute it freely, subject to the following restrictions:
16
+ //
17
+ // 1. The origin of this software must not be misrepresented; you must not
18
+ // claim that you wrote the original software. If you use this software
19
+ // in a product, an acknowledgment in the product documentation would be
20
+ // appreciated but is not required.
21
+ // 2. Altered source versions must be plainly marked as such, and must not be
22
+ // misrepresented as being the original software.
23
+ // 3. This notice may not be removed or altered from any source
24
+ // distribution.
25
+ //
26
+
27
+ #import "NSFOrderedDictionary.h"
28
+
29
+ @interface NSFOrderedDictionary ()
30
+ @property (nonatomic) NSMutableDictionary *dictionary;
31
+ @property (nonatomic) NSMutableArray *array;
32
+ @end
33
+
34
+ NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
35
+ {
36
+ NSString *objectString = nil;
37
+
38
+ if ([object isKindOfClass:[NSString class]]) {
39
+ objectString = (NSString *)object;
40
+ } else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
41
+ objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
42
+ } else if ([object respondsToSelector:@selector(descriptionWithLocale:)]) {
43
+ objectString = [(NSSet *)object descriptionWithLocale:locale];
44
+ } else {
45
+ objectString = [object description];
46
+ }
47
+
48
+ return objectString;
49
+ }
50
+
51
+ @implementation NSFOrderedDictionary
52
+
53
+ - (id)init
54
+ {
55
+ return [self initWithCapacity:0];
56
+ }
57
+
58
+ - (id)initWithCapacity:(NSUInteger)capacity
59
+ {
60
+ self = [super init];
61
+
62
+ if (self != nil) {
63
+ _dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
64
+ _array = [[NSMutableArray alloc] initWithCapacity:capacity];
65
+ }
66
+
67
+ return self;
68
+ }
69
+
70
+ - (id)copy
71
+ {
72
+ return [self mutableCopy];
73
+ }
74
+
75
+ - (void)setObject:(id)anObject forKey:(id)aKey
76
+ {
77
+ if (![_dictionary objectForKey:aKey]) {
78
+ [_array addObject:aKey];
79
+ }
80
+
81
+ [_dictionary setObject:anObject forKey:aKey];
82
+ }
83
+
84
+ - (void)removeObjectForKey:(id)aKey
85
+ {
86
+ [_dictionary removeObjectForKey:aKey];
87
+ [_array removeObject:aKey];
88
+ }
89
+
90
+ - (NSUInteger)count
91
+ {
92
+ return [_dictionary count];
93
+ }
94
+
95
+ - (id)objectForKey:(id)aKey
96
+ {
97
+ return [_dictionary objectForKey:aKey];
98
+ }
99
+
100
+ - (NSEnumerator *)keyEnumerator
101
+ {
102
+ return [_array objectEnumerator];
103
+ }
104
+
105
+ - (NSEnumerator *)reverseKeyEnumerator
106
+ {
107
+ return [_array reverseObjectEnumerator];
108
+ }
109
+
110
+ - (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
111
+ {
112
+ if ([_dictionary objectForKey:aKey]) {
113
+ [self removeObjectForKey:aKey];
114
+ }
115
+
116
+ [_array insertObject:aKey atIndex:anIndex];
117
+ [_dictionary setObject:anObject forKey:aKey];
118
+ }
119
+
120
+ - (id)keyAtIndex:(NSUInteger)anIndex
121
+ {
122
+ return [_array objectAtIndex:anIndex];
123
+ }
124
+
125
+ - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
126
+ {
127
+ NSMutableString *indentString = [NSMutableString string];
128
+ NSUInteger i, count = level;
129
+
130
+ for (i = 0; i < count; i++) {
131
+ [indentString appendFormat:@" "];
132
+ }
133
+
134
+ NSMutableString *description = [NSMutableString string];
135
+ [description appendFormat:@"%@{\n", indentString];
136
+
137
+ for (NSObject *key in self) {
138
+ [description appendFormat:@"%@ %@ = %@;\n",
139
+ indentString,
140
+ DescriptionForObject(key, locale, level),
141
+ DescriptionForObject([self objectForKey:key], locale, level)];
142
+ }
143
+
144
+ [description appendFormat:@"%@}\n", indentString];
145
+ return description;
146
+ }
147
+
148
+ @end