26 var _CPKeyedArchiverDidEncodeObjectSelector = 1,
27 _CPKeyedArchiverWillEncodeObjectSelector = 2,
28 _CPKeyedArchiverWillReplaceObjectWithObjectSelector = 4,
29 _CPKeyedArchiverDidFinishEncodingSelector = 8,
30 _CPKeyedArchiverWillFinishEncodingSelector = 16;
32 var _CPKeyedArchiverNullString =
"$null",
33 _CPKeyedArchiverNullReference = nil,
35 _CPKeyedArchiverUIDKey =
"CP$UID",
37 _CPKeyedArchiverTopKey =
"$top",
38 _CPKeyedArchiverObjectsKey =
"$objects",
39 _CPKeyedArchiverArchiverKey =
"$archiver",
40 _CPKeyedArchiverVersionKey =
"$version",
42 _CPKeyedArchiverClassNameKey =
"$classname",
43 _CPKeyedArchiverClassesKey =
"$classes",
44 _CPKeyedArchiverClassKey =
"$class";
46 var _CPKeyedArchiverStringClass = Nil,
47 _CPKeyedArchiverNumberClass = Nil;
50 @implementation _CPKeyedArchiverValue :
CPValue 98 unsigned _delegateSelectors;
113 CPPropertyListFormat _outputFormat;
127 _CPKeyedArchiverNullReference = @{ _CPKeyedArchiverUIDKey: 0 };
130 + (BOOL)allowsKeyedCoding
140 + (
CPData)archivedDataWithRootObject:(
id)anObject
145 [archiver encodeObject:anObject forKey:@"root"];
146 [archiver finishEncoding];
157 - (id)initForWritingWithMutableData:(CPMutableData)data
168 _conditionalUIDs = @{};
170 _replacementObjects = @{};
173 _plistObjects = [CPArray arrayWithObject:_CPKeyedArchiverNullString];
184 - (void)finishEncoding
186 if (_delegate && _delegateSelectors & _CPKeyedArchiverDidFinishEncodingSelector)
187 [_delegate archiverWillFinish:self];
190 topObject = _plistObject,
193 for (; i < _objects.length; ++i)
195 var
object = _objects[i];
200 _plistObject = _plistObjects[[_UIDs objectForKey:[object UID]]];
201 [object encodeWithCoder:self];
203 if (_delegate && _delegateSelectors & _CPKeyedArchiverDidEncodeObjectSelector)
204 [_delegate archiver:self didEncodeObject:object];
209 [_plistObject setObject:topObject forKey:_CPKeyedArchiverTopKey];
210 [_plistObject setObject:_plistObjects forKey:_CPKeyedArchiverObjectsKey];
211 [_plistObject setObject:[
self className] forKey:_CPKeyedArchiverArchiverKey];
212 [_plistObject setObject:@"100000" forKey:_CPKeyedArchiverVersionKey];
214 [_data setPlistObject:_plistObject];
216 if (_delegate && _delegateSelectors & _CPKeyedArchiverDidFinishEncodingSelector)
217 [_delegate archiverDidFinish:self];
223 - (CPPropertyListFormat)outputFormat
225 return _outputFormat;
232 - (void)setOutputFormat:(CPPropertyListFormat)aPropertyListFormat
234 _outputFormat = aPropertyListFormat;
242 - (void)encodeBool:(BOOL)aBOOL forKey:(
CPString)aKey
244 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, aBOOL, NO) forKey:aKey];
252 - (void)encodeDouble:(
double)aDouble forKey:(
CPString)aKey
254 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, aDouble, NO) forKey:aKey];
262 - (void)encodeFloat:(
float)aFloat forKey:(
CPString)aKey
264 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, aFloat, NO) forKey:aKey];
272 - (void)encodeInt:(
float)anInt forKey:(
CPString)aKey
274 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, anInt, NO) forKey:aKey];
281 - (void)setDelegate:(
id)aDelegate
283 _delegate = aDelegate;
285 if ([_delegate respondsToSelector:
@selector(archiver:didEncodeObject:)])
286 _delegateSelectors |= _CPKeyedArchiverDidEncodeObjectSelector;
288 if ([_delegate respondsToSelector:
@selector(archiver:willEncodeObject:)])
289 _delegateSelectors |= _CPKeyedArchiverWillEncodeObjectSelector;
291 if ([_delegate respondsToSelector:
@selector(archiver:willReplaceObject:withObject:)])
292 _delegateSelectors |= _CPKeyedArchiverWillReplaceObjectWithObjectSelector;
294 if ([_delegate respondsToSelector:
@selector(archiver:didFinishEncoding:)])
295 _delegateSelectors |= _CPKeyedArchiverDidFinishEncodingSelector;
297 if ([_delegate respondsToSelector:
@selector(archiver:willFinishEncoding:)])
298 _delegateSelectors |= _CPKeyedArchiverWillFinishEncodingSelector;
315 - (void)encodePoint:(CGPoint)aPoint forKey:(
CPString)aKey
317 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, CGStringFromPoint(aPoint), NO) forKey:aKey];
325 - (void)encodeRect:(CGRect)aRect forKey:(
CPString)aKey
327 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, CGStringFromRect(aRect), NO) forKey:aKey];
335 - (void)encodeSize:(CGSize)aSize forKey:(
CPString)aKey
337 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, CGStringFromSize(aSize), NO) forKey:aKey];
347 - (void)encodeConditionalObject:(
id)anObject forKey:(
CPString)aKey
349 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, anObject, YES) forKey:aKey];
359 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, aNumber, NO) forKey:aKey];
367 - (void)encodeObject:(
id)anObject forKey:(
CPString)aKey
369 [_plistObject setObject:_CPKeyedArchiverEncodeObject(self, anObject, NO) forKey:aKey];
373 - (void)_encodeArrayOfObjects:(CPArray)objects forKey:(
CPString)aKey
375 var references = [objects arrayByApplyingBlock:function(object)
377 return _CPKeyedArchiverEncodeObject(self, object, NO);
380 [_plistObject setObject:references forKey:aKey];
390 while ((key = [keys nextObject]) !== nil)
391 [references setObject:_CPKeyedArchiverEncodeObject(self, [aDictionary
objectForKey:key], NO) forKey:key];
393 [_plistObject setObject:references forKey:aKey];
404 + (void)setClassName:(
CPString)aClassName forClass:(Class)aClass
409 [CPArchiverReplacementClassNames setObject:aClassName forKey:CPStringFromClass(aClass)];
424 var className = [CPArchiverReplacementClassNames objectForKey:CPStringFromClass(aClass)];
426 return className ? className : aClass.name;
436 - (void)setClassName:(
CPString)aClassName forClass:(Class)aClass
438 if (!_replacementClassNames)
439 _replacementClassNames = @{};
441 [_replacementClassNames setObject:aClassName forKey:CPStringFromClass(aClass)];
449 - (
CPString)classNameForClass:(Class)aClass
451 if (!_replacementClassNames)
454 var className = [_replacementClassNames objectForKey:CPStringFromClass(aClass)];
456 return className ? className : aClass.name;
461 var _CPKeyedArchiverEncodeObject =
function(
self, anObject, isConditional)
466 if (anObject !== nil && anObject !== undefined && !anObject.isa)
467 anObject = [_CPKeyedArchiverValue valueWithJSObject:anObject];
470 var GUID = [anObject UID],
471 object = [
self._replacementObjects objectForKey:GUID];
477 object = [anObject replacementObjectForKeyedArchiver:self];
482 if (
object !== anObject &&
self._delegateSelectors & _CPKeyedArchiverWillReplaceObjectWithObjectSelector)
483 [
self._delegate archiver:self willReplaceObject:anObject withObject:object];
485 if (
self._delegateSelectors & _CPKeyedArchiverWillEncodeObjectSelector)
487 anObject = [
self._delegate archiver:self willEncodeObject:object];
489 if (anObject !==
object &&
self._delegateSelectors & _CPKeyedArchiverWillReplaceObjectWithObjectSelector)
490 [
self._delegate archiver:self willReplaceObject:object withObject:anObject];
496 if (
object != nil && GUID != nil)
497 [
self._replacementObjects setObject:object forKey:GUID];
504 return _CPKeyedArchiverNullReference;
507 var UID = [
self._UIDs objectForKey:GUID = [object UID]];
518 if ((UID = [
self._conditionalUIDs objectForKey:GUID]) === nil)
521 [
self._conditionalUIDs setObject:UID = [
self._plistObjects count] forKey:GUID];
522 [
self._plistObjects addObject:_CPKeyedArchiverNullString];
527 var theClass = [object classForKeyedArchiver],
530 if ((theClass === _CPKeyedArchiverStringClass) || (theClass === _CPKeyedArchiverNumberClass))
531 plistObject = object;
537 [
self._objects addObject:object];
539 var className = [
self classNameForClass:theClass];
542 className = [[
self class] classNameForClass:theClass];
545 className = theClass.name;
549 var classUID = [
self._UIDs objectForKey:className];
553 var plistClass = @{},
556 [plistClass setObject:className forKey:_CPKeyedArchiverClassNameKey];
560 [hierarchy addObject:CPStringFromClass(theClass)];
561 }
while (theClass = [theClass superclass]);
563 [plistClass setObject:hierarchy forKey:_CPKeyedArchiverClassesKey];
565 classUID = [
self._plistObjects count];
566 [
self._plistObjects addObject:plistClass];
567 [
self._UIDs setObject:classUID forKey:className];
570 [plistObject setObject:@{ _CPKeyedArchiverUIDKey: classUID } forKey:_CPKeyedArchiverClassKey];
573 UID = [
self._conditionalUIDs objectForKey:GUID];
578 [
self._UIDs setObject:UID forKey:GUID];
579 [
self._plistObjects replaceObjectAtIndex:UID withObject:plistObject];
583 [
self._UIDs setObject:UID = [
self._plistObjects count] forKey:GUID];
584 [
self._plistObjects addObject:plistObject];
589 return @{ _CPKeyedArchiverUIDKey: UID };
id initForWritingWithMutableData:(CPMutableData data)
CPEnumerator keyEnumerator()
A Cappuccino wrapper for any data type.
A mutable key-value pair collection.
A generic "value". Can be subclassed to hold specific data types.
Implements keyed archiving of object graphs (e.g. for storing data).
An immutable string (collection of characters).
id objectForKey:(id aKey)
Defines methods for use when archiving & restoring (enc/decoding).
var CPArchiverReplacementClassNames
A bridged object to native Javascript numbers.
CPData dataWithPlistObject:(id aPlistObject)
function CPClassFromString(aClassName)