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 _CPKeyedUnarchiverNumberClass = Nil,
00050 _CPKeyedUnarchiverDataClass = Nil,
00051 _CPKeyedUnarchiverArchiverValueClass = Nil;
00052
00097 @implementation CPKeyedUnarchiver : CPCoder
00098 {
00099 id _delegate;
00100 unsigned _delegateSelectors;
00101
00102 CPData _data;
00103
00104 CPDictionary _replacementClasses;
00105
00106 CPDictionary _objects;
00107 CPDictionary _archive;
00108
00109 CPDictionary _plistObject;
00110 CPArray _plistObjects;
00111 }
00112
00113
00114
00115
00116 + (void)initialize
00117 {
00118 if (self !== [CPKeyedUnarchiver class])
00119 return;
00120
00121 _CPKeyedUnarchiverArrayClass = [CPArray class];
00122 _CPKeyedUnarchiverStringClass = [CPString class];
00123 _CPKeyedUnarchiverDictionaryClass = [CPDictionary class];
00124 _CPKeyedUnarchiverNumberClass = [CPNumber class];
00125 _CPKeyedUnarchiverDataClass = [CPData class];
00126 _CPKeyedUnarchiverArchiverValueClass = [_CPKeyedArchiverValue class];
00127 }
00128
00129
00130
00131
00132
00133
00134 - (id)initForReadingWithData:(CPData)data
00135 {
00136 self = [super init];
00137
00138 if (self)
00139 {
00140 _archive = [data plistObject];
00141 _objects = [CPArray arrayWithObject:[CPNull null]];
00142
00143 _plistObject = [_archive objectForKey:_CPKeyedArchiverTopKey];
00144 _plistObjects = [_archive objectForKey:_CPKeyedArchiverObjectsKey];
00145
00146 _replacementClasses = [CPDictionary dictionary];
00147 }
00148
00149 return self;
00150 }
00151
00152
00153
00154
00155
00156
00157 + (id)unarchiveObjectWithData:(CPData)data
00158 {
00159 var unarchiver = [[self alloc] initForReadingWithData:data],
00160 object = [unarchiver decodeObjectForKey:@"root"];
00161
00162 [unarchiver finishDecoding];
00163
00164 return object;
00165 }
00166
00167
00168
00169
00170 + (id)unarchiveObjectWithFile:(CPString)aFilePath
00171 {
00172 }
00173
00174
00175
00176
00177 + (id)unarchiveObjectWithFile:(CPString)aFilePath asynchronously:(BOOL)aFlag
00178 {
00179 }
00180
00181
00182
00183
00184
00185 - (BOOL)containsValueForKey:(CPString)aKey
00186 {
00187 return [_plistObject objectForKey:aKey] != nil;
00188 }
00189
00190
00191 - (void)_decodeDictionaryOfObjectsForKey:(CPString)aKey
00192 {
00193 var object = [_plistObject objectForKey:aKey];
00194
00195 if ([object isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00196 {
00197 var key,
00198 keys = [object keyEnumerator],
00199 dictionary = [CPDictionary dictionary];
00200
00201 while (key = [keys nextObject])
00202 [dictionary setObject:_CPKeyedUnarchiverDecodeObjectAtIndex(self, [[object objectForKey:key] objectForKey:_CPKeyedArchiverUIDKey]) forKey:key];
00203
00204 return dictionary;
00205 }
00206
00207 return nil;
00208 }
00209
00210
00211
00212
00213
00214
00215 - (BOOL)decodeBoolForKey:(CPString)aKey
00216 {
00217 return [self decodeObjectForKey:aKey];
00218 }
00219
00220
00221
00222
00223
00224
00225 - (float)decodeFloatForKey:(CPString)aKey
00226 {
00227 return [self decodeObjectForKey:aKey];
00228 }
00229
00230
00231
00232
00233
00234
00235 - (double)decodeDoubleForKey:(CPString)aKey
00236 {
00237 return [self decodeObjectForKey:aKey];
00238 }
00239
00240
00241
00242
00243
00244
00245 - (int)decodeIntForKey:(CPString)aKey
00246 {
00247 return [self decodeObjectForKey:aKey];
00248 }
00249
00250
00251
00252
00253
00254
00255 - (CGPoint)decodePointForKey:(CPString)aKey
00256 {
00257 var object = [self decodeObjectForKey:aKey];
00258
00259 if(object)
00260 return CPPointFromString(object);
00261 else
00262 return CPPointMake(0.0, 0.0);
00263 }
00264
00265
00266
00267
00268
00269
00270 - (CGRect)decodeRectForKey:(CPString)aKey
00271 {
00272 var object = [self decodeObjectForKey:aKey];
00273
00274 if(object)
00275 return CPRectFromString(object);
00276 else
00277 return CPRectMakeZero();
00278 }
00279
00280
00281
00282
00283
00284
00285 - (CGSize)decodeSizeForKey:(CPString)aKey
00286 {
00287 var object = [self decodeObjectForKey:aKey];
00288
00289 if(object)
00290 return CPSizeFromString(object);
00291 else
00292 return CPSizeMake(0.0, 0.0);
00293 }
00294
00295
00296
00297
00298
00299
00300 - (id)decodeObjectForKey:(CPString)aKey
00301 {
00302 var object = [_plistObject objectForKey:aKey];
00303
00304 if ([object isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00305 return _CPKeyedUnarchiverDecodeObjectAtIndex(self, [object objectForKey:_CPKeyedArchiverUIDKey]);
00306
00307 else if ([object isKindOfClass:_CPKeyedUnarchiverNumberClass] || [object isKindOfClass:_CPKeyedUnarchiverDataClass])
00308 return object;
00309
00310 else if ([object isKindOfClass:_CPKeyedUnarchiverArrayClass])
00311 {
00312 var index = 0,
00313 count = object.length,
00314 array = [];
00315
00316 for (; index < count; ++index)
00317 array[index] = _CPKeyedUnarchiverDecodeObjectAtIndex(self, [object[index] objectForKey:_CPKeyedArchiverUIDKey]);
00318
00319 return array;
00320 }
00321
00322
00323
00324 return nil;
00325 }
00326
00327
00328
00329
00330
00331
00332 - (id)decodeBytesForKey:(CPString)aKey
00333 {
00334
00335 var data = [self decodeObjectForKey:aKey];
00336
00337 if ([data isKindOfClass:[CPData class]])
00338 return data.bytes;
00339
00340 return nil;
00341 }
00342
00343
00344
00345
00346 - (void)finishDecoding
00347 {
00348 if (_delegateSelectors & _CPKeyedUnarchiverWillFinishSelector)
00349 [_delegate unarchiverWillFinish:self];
00350
00351 if (_delegateSelectors & _CPKeyedUnarchiverDidFinishSelector)
00352 [_delegate unarchiverDidFinish:self];
00353 }
00354
00355
00356
00357
00358 - (id)delegate
00359 {
00360 return _delegate;
00361 }
00362
00363
00364
00365
00366
00367 - (void)setDelegate:(id)aDelegate
00368 {
00369 _delegate = aDelegate;
00370
00371 if ([_delegate respondsToSelector:@selector(unarchiver:cannotDecodeObjectOfClassName:originalClasses:)])
00372 _delegateSelectors |= _CPKeyedUnarchiverCannotDecodeObjectOfClassNameOriginalClassesSelector;
00373
00374 if ([_delegate respondsToSelector:@selector(unarchiver:didDecodeObject:)])
00375 _delegateSelectors |= _CPKeyedUnarchiverDidDecodeObjectSelector;
00376
00377 if ([_delegate respondsToSelector:@selector(unarchiver:willReplaceObject:withObject:)])
00378 _delegateSelectors |= _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector;
00379
00380 if ([_delegate respondsToSelector:@selector(unarchiverWillFinish:)])
00381 _delegateSelectors |= _CPKeyedUnarchiverWilFinishSelector;
00382
00383 if ([_delegate respondsToSelector:@selector(unarchiverDidFinish:)])
00384 _delegateSelectors |= _CPKeyedUnarchiverDidFinishSelector;
00385 }
00386
00387 - (void)setClass:(Class)aClass forClassName:(CPString)aClassName
00388 {
00389 [_replacementClasses setObject:aClass forKey:aClassName];
00390 }
00391
00392 - (Class)classForClassName:(CPString)aClassName
00393 {
00394 return [_replacementClasses objectForKey:aClassName];
00395 }
00396
00397 - (BOOL)allowsKeyedCoding
00398 {
00399 return YES;
00400 }
00401
00402 @end
00403
00404 var _CPKeyedUnarchiverDecodeObjectAtIndex = function(self, anIndex)
00405 {
00406 var object = self._objects[anIndex];
00407
00408 if (object)
00409 if (object == self._objects[0])
00410 return nil;
00411 else
00412 return object;
00413
00414 var object,
00415 plistObject = self._plistObjects[anIndex];
00416
00417 if ([plistObject isKindOfClass:_CPKeyedUnarchiverDictionaryClass])
00418 {
00419 var plistClass = self._plistObjects[[[plistObject objectForKey:_CPKeyedArchiverClassKey] objectForKey:_CPKeyedArchiverUIDKey]],
00420 className = [plistClass objectForKey:_CPKeyedArchiverClassNameKey],
00421 classes = [plistClass objectForKey:_CPKeyedArchiverClassesKey],
00422 theClass = [self classForClassName:className];
00423
00424 if (!theClass)
00425 theClass = CPClassFromString(className);
00426
00427 object = [theClass alloc];
00428
00429
00430 self._objects[anIndex] = object;
00431
00432 var savedPlistObject = self._plistObject;
00433
00434 self._plistObject = plistObject;
00435 var string = className;
00436 var processedObject = [object initWithCoder:self];
00437
00438 self._plistObject = savedPlistObject;
00439
00440 if (processedObject != object)
00441 {
00442 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00443 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00444
00445 object = processedObject;
00446 self._objects[anIndex] = processedObject;
00447 }
00448
00449 processedObject = [object awakeAfterUsingCoder:self];
00450
00451 if (processedObject != object)
00452 {
00453 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00454 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00455
00456 object = processedObject;
00457 self._objects[anIndex] = processedObject;
00458 }
00459
00460 if (self._delegate)
00461 {
00462 if (self._delegateSelectors & _CPKeyedUnarchiverDidDecodeObjectSelector)
00463 processedObject = [self._delegate unarchiver:self didDecodeObject:object];
00464
00465 if (processedObject != object)
00466 {
00467 if (self._delegateSelectors & _CPKeyedUnarchiverWillReplaceObjectWithObjectSelector)
00468 [self._delegate unarchiver:self willReplaceObject:object withObject:processedObject];
00469
00470 object = processedObject;
00471 self._objects[anIndex] = processedObject;
00472 }
00473 }
00474 }
00475 else
00476 {
00477 self._objects[anIndex] = object = plistObject;
00478
00479 if ([object class] == _CPKeyedUnarchiverStringClass)
00480 {
00481 if (object == _CPKeyedArchiverNullString)
00482 {
00483 self._objects[anIndex] = self._objects[0];
00484
00485 return nil;
00486 }
00487 else
00488 self._objects[anIndex] = object = plistObject;
00489 }
00490 }
00491
00492
00493
00494 if ([object isMemberOfClass:_CPKeyedUnarchiverArchiverValueClass])
00495 object = [object JSObject];
00496
00497 return object;
00498 }
00499