00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 @import "CPObject.j"
00025 @import "CPEnumerator.j"
00026 @import "CPException.j"
00027
00028
00029 @implementation _CPDictionaryValueEnumerator : CPEnumerator
00030 {
00031 CPEnumerator _keyEnumerator;
00032 CPDictionary _dictionary;
00033 }
00034
00035 - (id)initWithDictionary:(CPDictionary)aDictionary
00036 {
00037 self = [super init];
00038
00039 if (self)
00040 {
00041 _keyEnumerator = [aDictionary keyEnumerator];
00042 _dictionary = aDictionary;
00043 }
00044
00045 return self;
00046 }
00047
00048 - (id)nextObject
00049 {
00050 var key = [_keyEnumerator nextObject];
00051
00052 if (!key)
00053 return nil;
00054
00055 return [_dictionary objectForKey:key];
00056 }
00057
00058 @end
00059
00075 @implementation CPDictionary : CPObject
00076 {
00077 }
00078
00079
00080
00081
00082 + (id)alloc
00083 {
00084 return new objj_dictionary();
00085 }
00086
00090 + (id)dictionary
00091 {
00092 return [[self alloc] init];
00093 }
00094
00100 + (id)dictionaryWithDictionary:(CPDictionary)aDictionary
00101 {
00102 return [[self alloc] initWithDictionary:aDictionary];
00103 }
00104
00111 + (id)dictionaryWithObject:(id)anObject forKey:(id)aKey
00112 {
00113 return [[self alloc] initWithObjects:[anObject] forKeys:[aKey]];
00114 }
00115
00123 + (id)dictionaryWithObjects:(CPArray)objects forKeys:(CPArray)keys
00124 {
00125 return [[self alloc] initWithObjects:objects forKeys:keys];
00126 }
00127
00133 + (id)dictionaryWithJSObject:(JSObject)object
00134 {
00135 return [self dictionaryWithJSObject:object recursively:NO];
00136 }
00137
00143 + (id)dictionaryWithJSObject:(JSObject)object recursively:(BOOL)recursively
00144 {
00145 var dictionary = [[self alloc] init];
00146
00147 for (var key in object)
00148 {
00149 var value = object[key];
00150
00151 if (recursively && value.constructor === Object)
00152 value = [CPDictionary dictionaryWithJSObject:value recursively:YES];
00153
00154 [dictionary setObject:value forKey:key];
00155 }
00156
00157 return dictionary;
00158 }
00159
00177 + (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...
00178 {
00179 arguments[0] = [self alloc];
00180 arguments[1] = @selector(initWithObjectsAndKeys:);
00181
00182 return objj_msgSend.apply(this, arguments);
00183 }
00184
00190 - (id)initWithDictionary:(CPDictionary)aDictionary
00191 {
00192 var key = "",
00193 dictionary = [[CPDictionary alloc] init];
00194
00195 for (key in aDictionary._buckets)
00196 [dictionary setObject:[aDictionary objectForKey:key] forKey:key];
00197
00198 return dictionary;
00199 }
00200
00208 - (id)initWithObjects:(CPArray)objects forKeys:(CPArray)keyArray
00209 {
00210 self = [super init];
00211
00212 if ([objects count] != [keyArray count])
00213 [CPException raise:CPInvalidArgumentException reason:"Counts are different.("+[objects count]+"!="+[keyArray count]+")"];
00214
00215 if (self)
00216 {
00217 var i = [keyArray count];
00218
00219 while (i--)
00220 [self setObject:objects[i] forKey:keyArray[i]];
00221 }
00222
00223 return self;
00224 }
00225
00240 - (id)initWithObjectsAndKeys:(id)firstObject, ...
00241 {
00242 var argCount = arguments.length;
00243
00244 if (argCount % 2 !== 0)
00245 [CPException raise:CPInvalidArgumentException reason:"Key-value count is mismatched. (" + argCount + " arguments passed)"];
00246
00247 self = [super init];
00248
00249 if (self)
00250 {
00251
00252 var index = 2;
00253
00254 for(; index < argCount; index += 2)
00255 {
00256 var value = arguments[index];
00257
00258 if (value === nil)
00259 break;
00260
00261 [self setObject:value forKey:arguments[index + 1]];
00262 }
00263 }
00264
00265 return self;
00266 }
00267
00271 - (CPDictionary)copy
00272 {
00273 return [CPDictionary dictionaryWithDictionary:self];
00274 }
00275
00279 - (int)count
00280 {
00281 return count;
00282 }
00283
00287 - (CPArray)allKeys
00288 {
00289 return _keys;
00290 }
00291
00295 - (CPArray)allValues
00296 {
00297 var index = _keys.length,
00298 values = [];
00299
00300 while (index--)
00301 values.push(dictionary_getValue(self, [_keys[index]]));
00302
00303 return values;
00304 }
00305
00309 - (CPEnumerator)keyEnumerator
00310 {
00311 return [_keys objectEnumerator];
00312 }
00313
00317 - (CPEnumerator)objectEnumerator
00318 {
00319 return [[_CPDictionaryValueEnumerator alloc] initWithDictionary:self];
00320 }
00321
00325 - (BOOL)isEqualToDictionary:(CPDictionary)aDictionary
00326 {
00327 if (count !== [aDictionary count])
00328 return NO;
00329
00330 var index = count;
00331 while (index--)
00332 {
00333 var currentKey = _keys[index],
00334 lhsObject = _buckets[currentKey],
00335 rhsObject = aDictionary._buckets[currentKey];
00336
00337 if (lhsObject === rhsObject)
00338 continue;
00339
00340 if (lhsObject.isa && rhsObject.isa && [lhsObject respondsToSelector:@selector(isEqual:)] && [lhsObject isEqual:rhsObject])
00341 continue;
00342
00343 return NO;
00344 }
00345
00346 return YES;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00407 - (id)objectForKey:(CPString)aKey
00408 {
00409 var object = _buckets[aKey];
00410
00411 return (object === undefined) ? nil : object;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00448 - (void)removeAllObjects
00449 {
00450 _keys = [];
00451 count = 0;
00452 _buckets = {};
00453 }
00454
00459 - (void)removeObjectForKey:(id)aKey
00460 {
00461 dictionary_removeValue(self, aKey);
00462 }
00463
00468 - (void)removeObjectsForKeys:(CPArray)allKeys
00469 {
00470 var index = allKeys.length;
00471
00472 while (index--)
00473 dictionary_removeValue(self, allKeys[index]);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00508 - (void)setObject:(id)anObject forKey:(id)aKey
00509 {
00510 dictionary_setValue(self, aKey, anObject);
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00528 - (void)addEntriesFromDictionary:(CPDictionary)aDictionary
00529 {
00530 if (!aDictionary)
00531 return;
00532
00533 var keys = [aDictionary allKeys],
00534 index = [keys count];
00535
00536 while (index--)
00537 {
00538 var key = keys[index];
00539
00540 [self setObject:[aDictionary objectForKey:key] forKey:key];
00541 }
00542 }
00543
00547 - (CPString)description
00548 {
00549 var description = @"CPDictionary {\n";
00550
00551 var i = _keys.length;
00552
00553 while (i--)
00554 {
00555 description += _keys[i] + ":";
00556
00557 var object = _buckets[_keys[i]];
00558
00559 if (object && object.isa)
00560 description += [object description];
00561 else
00562 description += object;
00563
00564 description += "\n";
00565 }
00566
00567 description += "}";
00568
00569 return description;
00570 }
00571
00572 @end
00573
00574 @implementation CPDictionary (CPCoding)
00575
00576
00577
00578
00579
00580
00581 - (id)initWithCoder:(CPCoder)aCoder
00582 {
00583 return [aCoder _decodeDictionaryOfObjectsForKey:@"CP.objects"];
00584 }
00585
00590 - (void)encodeWithCoder:(CPCoder)aCoder
00591 {
00592 [aCoder _encodeDictionaryOfObjects:self forKey:@"CP.objects"];
00593 }
00594
00595 @end
00596
00602 @implementation CPMutableDictionary : CPDictionary
00603
00604 @end
00605
00606 objj_dictionary.prototype.isa = CPDictionary;