00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "CPNull.j"
00024 @import "CPCoder.j"
00025
00026
00027 var _CPKeyedUnarchiverCannotDecodeObjectOfClassNameOriginalClassesSelector = 1,
00028 _CPKeyedUnarchiverDidDecodeObjectSelector = 1 << 1,
00029 _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector = 1 << 2,
00030 _CPKeyedUnarchiverWillFinishSelector = 1 << 3,
00031 _CPKeyedUnarchiverDidFinishSelector = 1 << 4;
00032
00033 var _CPKeyedArchiverNullString = "$null"
00034
00035 _CPKeyedArchiverUIDKey = "CP$UID",
00036
00037 _CPKeyedArchiverTopKey = "$top",
00038 _CPKeyedArchiverObjectsKey = "$objects",
00039 _CPKeyedArchiverArchiverKey = "$archiver",
00040 _CPKeyedArchiverVersionKey = "$version",
00041
00042 _CPKeyedArchiverClassNameKey = "$classname",
00043 _CPKeyedArchiverClassesKey = "$classes",
00044 _CPKeyedArchiverClassKey = "$class";
00045
00046 var _CPKeyedUnarchiverArrayClass = Nil,
00047 _CPKeyedUnarchiverStringClass = Nil,
00048 _CPKeyedUnarchiverDictionaryClass = Nil,
00049 _CPKeyedUnarchiverArchiverValueClass = Nil;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 @implementation CPKeyedUnarchiver : CPCoder
00094 {
00095 id _delegate;
00096 unsigned _delegateSelectors;
00097
00098 CPData _data;
00099
00100
00101 CPDictionary _replacementClassNames;
00102
00103 CPDictionary _objects;
00104 CPDictionary _archive;
00105
00106 CPDictionary _plistObject;
00107 CPArray _plistObjects;
00108 }
00109
00110
00111
00112
00113 + (void)initialize
00114 {
00115 if (self != [CPKeyedUnarchiver class])
00116 return;
00117
00118 _CPKeyedUnarchiverArrayClass = [CPArray class];
00119 _CPKeyedUnarchiverStringClass = [CPString class];
00120 _CPKeyedUnarchiverDictionaryClass = [CPDictionary class];
00121 _CPKeyedUnarchiverArchiverValueClass = [_CPKeyedArchiverValue class];
00122 }
00123
00124
00125
00126
00127
00128
00129 - (id)initForReadingWithData:(CPData)data
00130 {
00131 self = [super init];
00132
00133 if (self)
00134 {
00135 _archive = [data plistObject];
00136 _objects = [CPArray arrayWithObject:[CPNull null]];
00137
00138 _plistObject = [_archive objectForKey:_CPKeyedArchiverTopKey];
00139 _plistObjects = [_archive objectForKey:_CPKeyedArchiverObjectsKey];
00140 }
00141
00142 return self;
00143 }
00144
00145
00146
00147
00148
00149
00150 + (id)unarchiveObjectWithData:(CPData)data
00151 {
00152 var unarchiver = [[self alloc] initForReadingWithData:data],
00153 object = [unarchiver decodeObjectForKey:@"root"];
00154
00155 [unarchiver finishDecoding];
00156
00157 return object;
00158 }
00159
00160
00161
00162
00163 + (id)unarchiveObjectWithFile:(CPString)aFilePath
00164 {
00165 }
00166
00167
00168
00169
00170 + (id)unarchiveObjectWithFile:(CPString)aFilePath asynchronously:(BOOL)aFlag
00171 {
00172 }
00173
00174
00175
00176
00177
00178 - (BOOL)containsValueForKey:(CPString)aKey
00179 {
00180 return [_plistObject objectForKey:aKey] != nil;
00181 }
00182
00183
00184 - (id)_decodeArrayOfObjectsForKey:(CPString)aKey
00185 {
00186 var object = [_plistObject objectForKey:aKey];
00187
00188 if ([object isKindOfClass:_CPKeyedUnarchiverArrayClass])
00189 {
00190 var index = 0,
00191 count = object.length,
00192 array = [];
00193
00194 for (; index < count; ++index)
00195 array[index] = _CPKeyedUnarchiverDecodeObjectAtIndex(self, [object[index] objectForKey:_CPKeyedArchiverUIDKey]);
00196
00197 return array;
00198 }
00199
00200 return nil;
00201 }
00202
00203
00204 - (void)_decodeDictionaryOfObjectsForKey:(CPString)aKey
00205 {
00206 var object = [_plistObject objectForKey:aKey];
00207
00208 if ([object isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00209 {
00210 var key,
00211 keys = [object keyEnumerator],
00212 dictionary = [CPDictionary dictionary];
00213
00214 while (key = [keys nextObject])
00215 [dictionary setObject:_CPKeyedUnarchiverDecodeObjectAtIndex(self, [[object objectForKey:key] objectForKey:_CPKeyedArchiverUIDKey]) forKey:key];
00216
00217 return dictionary;
00218 }
00219
00220 return nil;
00221 }
00222
00223
00224
00225
00226
00227
00228 - (BOOL)decodeBoolForKey:(CPString)aKey
00229 {
00230 return [self decodeObjectForKey:aKey];
00231 }
00232
00233
00234
00235
00236
00237
00238 - (float)decodeFloatForKey:(CPString)aKey
00239 {
00240 return [self decodeObjectForKey:aKey];
00241 }
00242
00243
00244
00245
00246
00247
00248 - (double)decodeDoubleForKey:(CPString)aKey
00249 {
00250 return [self decodeObjectForKey:aKey];
00251 }
00252
00253
00254
00255
00256
00257
00258 - (int)decodeIntForKey:(CPString)aKey
00259 {
00260 return [self decodeObjectForKey:aKey];
00261 }
00262
00263
00264
00265
00266
00267
00268 - (CGPoint)decodePointForKey:(CPString)aKey
00269 {
00270 var object = [self decodeObjectForKey:aKey];
00271
00272 if(object)
00273 return CPPointFromString(object);
00274 else
00275 return CPPointMake(0.0, 0.0);
00276 }
00277
00278
00279
00280
00281
00282
00283 - (CGRect)decodeRectForKey:(CPString)aKey
00284 {
00285 var object = [self decodeObjectForKey:aKey];
00286
00287 if(object)
00288 return CPRectFromString(object);
00289 else
00290 return CPRectMakeZero();
00291 }
00292
00293
00294
00295
00296
00297
00298 - (CGSize)decodeSizeForKey:(CPString)aKey
00299 {
00300 var object = [self decodeObjectForKey:aKey];
00301
00302 if(object)
00303 return CPSizeFromString(object);
00304 else
00305 return CPSizeMake(0.0, 0.0);
00306 }
00307
00308
00309
00310
00311
00312
00313 - (id)decodeObjectForKey:(CPString)aKey
00314 {
00315 var object = [_plistObject objectForKey:aKey];
00316
00317 if ([object isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00318 return _CPKeyedUnarchiverDecodeObjectAtIndex(self, [object objectForKey:_CPKeyedArchiverUIDKey]);
00319 else if ([object isKindOfClass:[CPNumber class]])
00320 return object;
00321
00322
00323
00324 return nil;
00325 }
00326
00327
00328
00329
00330 - (void)finishDecoding
00331 {
00332 if (_delegateSelectors & _CPKeyedUnarchiverWillFinishSelector)
00333 [_delegate unarchiverWillFinish:self];
00334
00335 if (_delegateSelectors & _CPKeyedUnarchiverDidFinishSelector)
00336 [_delegate unarchiverDidFinish:self];
00337 }
00338
00339
00340
00341
00342 - (id)delegate
00343 {
00344 return _delegate;
00345 }
00346
00347
00348
00349
00350
00351 - (void)setDelegate:(id)aDelegate
00352 {
00353 _delegate = aDelegate;
00354
00355 if ([_delegate respondsToSelector:@selector(unarchiver:cannotDecodeObjectOfClassName:originalClasses:)])
00356 _delegateSelectors |= _CPKeyedUnarchiverCannotDecodeObjectOfClassNameOriginalClassesSelector;
00357
00358 if ([_delegate respondsToSelector:@selector(unarchiver:didDecodeObject:)])
00359 _delegateSelectors |= _CPKeyedUnarchiverDidDecodeObjectSelector;
00360
00361 if ([_delegate respondsToSelector:@selector(unarchiver:willReplaceObject:withObject:)])
00362 _delegateSelectors |= _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector;
00363
00364 if ([_delegate respondsToSelector:@selector(unarchiverWillFinish:)])
00365 _delegateSelectors |= _CPKeyedUnarchiverWilFinishSelector;
00366
00367 if ([_delegate respondsToSelector:@selector(unarchiverDidFinish:)])
00368 _delegateSelectors |= _CPKeyedUnarchiverDidFinishSelector;
00369 }
00370
00371 - (BOOL)allowsKeyedCoding
00372 {
00373 return YES;
00374 }
00375
00376 @end
00377
00378 var _CPKeyedUnarchiverDecodeObjectAtIndex = function(self, anIndex)
00379 {
00380 var object = self._objects[anIndex];
00381
00382 if (object)
00383 if (object == self._objects[0])
00384 return nil;
00385 else
00386 return object;
00387
00388 var object,
00389 plistObject = self._plistObjects[anIndex];
00390
00391 if ([plistObject isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00392 {
00393 var plistClass = self._plistObjects[[[plistObject objectForKey:_CPKeyedArchiverClassKey] objectForKey:_CPKeyedArchiverUIDKey]],
00394 className = [plistClass objectForKey:_CPKeyedArchiverClassNameKey],
00395 classes = [plistClass objectForKey:_CPKeyedArchiverClassesKey],
00396 theClass = CPClassFromString(className);
00397
00398 object = [theClass alloc];
00399
00400
00401 self._objects[anIndex] = object;
00402
00403 var savedPlistObject = self._plistObject;
00404
00405 self._plistObject = plistObject;
00406
00407 var processedObject = [object initWithCoder:self];
00408
00409 self._plistObject = savedPlistObject;
00410
00411 if (processedObject != object)
00412 {
00413 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00414 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00415
00416 object = processedObject;
00417 self._objects[anIndex] = processedObject;
00418 }
00419
00420 processedObject = [object awakeAfterUsingCoder:self];
00421
00422 if (processedObject != object)
00423 {
00424 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00425 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00426
00427 object = processedObject;
00428 self._objects[anIndex] = processedObject;
00429 }
00430
00431 if (self._delegate)
00432 {
00433 if (self._delegateSelectors & _CPKeyedUnarchiverDidDecodeObjectSelector)
00434 processedObject = [self._delegate unarchiver:self didDecodeObject:object];
00435
00436 if (processedObject != object)
00437 {
00438 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00439 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00440
00441 object = processedObject;
00442 self._objects[anIndex] = processedObject;
00443 }
00444 }
00445 }
00446 else
00447 {
00448 self._objects[anIndex] = object = plistObject;
00449
00450 if ([object class] == _CPKeyedUnarchiverStringClass)
00451 {
00452 if (object == _CPKeyedArchiverNullString)
00453 {
00454 self._objects[anIndex] = self._objects[0];
00455
00456 return nil;
00457 }
00458 else
00459 self._objects[anIndex] = object = plistObject;
00460 }
00461 }
00462
00463
00464
00465 if ([object isMemberOfClass:_CPKeyedUnarchiverArchiverValueClass])
00466 object = [object JSObject];
00467
00468 return object;
00469 }
00470