2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "EOKeyValueArchiver.h"
25 @implementation EOKeyValueArchiver
28 if ((self = [super init])) {
29 self->plist = [[NSMutableDictionary alloc] init];
35 [self->plist release];
41 static BOOL isPListObject(id _obj) {
42 if ([_obj isKindOfClass:[NSString class]])
44 if ([_obj isKindOfClass:[NSData class]])
46 if ([_obj isKindOfClass:[NSArray class]])
51 - (void)encodeObject:(id)_obj forKey:(NSString *)_key {
52 NSMutableDictionary *oldPlist;
54 if (isPListObject(_obj)) {
57 [self->plist setObject:c forKey:_key];
62 oldPlist = self->plist;
63 self->plist = [[NSMutableDictionary alloc] init];
66 /* store class name */
67 [self->plist setObject:NSStringFromClass([_obj class]) forKey:@"class"];
69 /* let object store itself */
70 [_obj encodeWithKeyValueArchiver:self];
76 [oldPlist setObject:self->plist forKey:_key];
77 [self->plist release];
78 self->plist = oldPlist;
81 - (void)encodeReferenceToObject:(id)_obj forKey:(NSString *)_key {
82 if ([self->delegate respondsToSelector:
83 @selector(archiver:referenceToEncodeForObject:)])
84 _obj = [self->delegate archiver:self referenceToEncodeForObject:_obj];
86 /* if _obj wasn't replaced by the delegate, encode the object in place .. */
87 [self encodeObject:_obj forKey:_key];
90 - (void)encodeBool:(BOOL)_flag forKey:(NSString *)_key {
91 /* NO values are not archived .. */
93 [self->plist setObject:@"YES" forKey:_key];
96 - (void)encodeInt:(int)_value forKey:(NSString *)_key {
97 [self->plist setObject:[NSString stringWithFormat:@"%i", _value] forKey:_key];
100 - (NSDictionary *)dictionary {
101 return [[self->plist copy] autorelease];
106 - (void)setDelegate:(id)_delegate {
107 self->delegate = _delegate;
110 return self->delegate;
113 @end /* EOKeyValueArchiver */
115 @implementation EOKeyValueUnarchiver
117 - (id)initWithDictionary:(NSDictionary *)_dict {
118 self->plist = [_dict copy];
119 self->unarchivedObjects = [[NSMutableArray alloc] init];
120 self->awakeObjects = [[NSMutableSet alloc] init]; // should be a hashtable
129 [self->awakeObjects release];
130 [self->unarchivedObjects release];
131 [self->plist release];
137 - (id)decodeObjectForKey:(NSString *)_key {
139 NSDictionary *lastParent;
142 lastParent = self->parent;
143 self->parent = self->plist;
144 self->plist = [(NSDictionary *)self->parent objectForKey:_key];
146 if (![self->plist isKindOfClass:[NSDictionary class]]) {
147 obj = [[self->plist copy] autorelease];
149 else if ((className = [self->plist objectForKey:@"class"]) != nil) {
150 obj = [NSClassFromString(className) alloc];
151 obj = [obj initWithKeyValueUnarchiver:self];
153 [self->unarchivedObjects addObject:obj];
160 self->plist = self->parent;
161 self->parent = lastParent;
165 - (id)decodeObjectReferenceForKey:(NSString *)_key {
168 refObj = [self decodeObjectForKey:_key];
170 if ([self->delegate respondsToSelector:
171 @selector(unarchiver:objectForReference:)]) {
172 obj = [self->delegate unarchiver:self objectForReference:refObj];
174 [self->unarchivedObjects addObject:obj];
177 /* if delegate does not dereference, pass back the reference object */
183 - (BOOL)decodeBoolForKey:(NSString *)_key {
184 return [[self->plist objectForKey:_key] boolValue];
186 - (int)decodeIntForKey:(NSString *)_key {
187 return [[self->plist objectForKey:_key] intValue];
192 - (void)ensureObjectAwake:(id)_object {
193 if (![self->awakeObjects containsObject:_object]) {
194 if ([_object respondsToSelector:@selector(awakeFromKeyValueUnarchiver:)]) {
195 [_object awakeFromKeyValueUnarchiver:self];
197 [self->awakeObjects addObject:_object];
200 - (void)awakeObjects {
204 e = [self->unarchivedObjects objectEnumerator];
205 while ((obj = [e nextObject]))
206 [self ensureObjectAwake:obj];
209 - (void)finishInitializationOfObjects {
213 e = [self->unarchivedObjects objectEnumerator];
214 while ((obj = [e nextObject])) {
215 if ([obj respondsToSelector:
216 @selector(finishInitializationWithKeyValueUnarchiver:)])
217 [obj finishInitializationWithKeyValueUnarchiver:self];
227 - (void)setDelegate:(id)_delegate {
228 self->delegate = _delegate;
231 return self->delegate;
234 @end /* EOKeyValueUnarchiver */