2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "EOKeyValueArchiver.h"
26 @implementation EOKeyValueArchiver
29 if ((self = [super init])) {
30 self->plist = [[NSMutableDictionary alloc] init];
36 [self->plist release];
42 static BOOL isPListObject(id _obj) {
43 if ([_obj isKindOfClass:[NSString class]])
45 if ([_obj isKindOfClass:[NSData class]])
47 if ([_obj isKindOfClass:[NSArray class]])
52 - (void)encodeObject:(id)_obj forKey:(NSString *)_key {
53 NSMutableDictionary *oldPlist;
55 if (isPListObject(_obj)) {
58 [self->plist setObject:c forKey:_key];
63 oldPlist = self->plist;
64 self->plist = [[NSMutableDictionary alloc] init];
67 /* store class name */
68 [self->plist setObject:NSStringFromClass([_obj class]) forKey:@"class"];
70 /* let object store itself */
71 [_obj encodeWithKeyValueArchiver:self];
77 [oldPlist setObject:self->plist forKey:_key];
78 [self->plist release];
79 self->plist = oldPlist;
82 - (void)encodeReferenceToObject:(id)_obj forKey:(NSString *)_key {
83 if ([self->delegate respondsToSelector:
84 @selector(archiver:referenceToEncodeForObject:)])
85 _obj = [self->delegate archiver:self referenceToEncodeForObject:_obj];
87 /* if _obj wasn't replaced by the delegate, encode the object in place .. */
88 [self encodeObject:_obj forKey:_key];
91 - (void)encodeBool:(BOOL)_flag forKey:(NSString *)_key {
92 /* NO values are not archived .. */
94 [self->plist setObject:@"YES" forKey:_key];
97 - (void)encodeInt:(int)_value forKey:(NSString *)_key {
98 [self->plist setObject:[NSString stringWithFormat:@"%i", _value] forKey:_key];
101 - (NSDictionary *)dictionary {
102 return [[self->plist copy] autorelease];
107 - (void)setDelegate:(id)_delegate {
108 self->delegate = _delegate;
111 return self->delegate;
114 @end /* EOKeyValueArchiver */
116 @implementation EOKeyValueUnarchiver
118 - (id)initWithDictionary:(NSDictionary *)_dict {
119 self->plist = [_dict copy];
120 self->unarchivedObjects = [[NSMutableArray alloc] init];
121 self->awakeObjects = [[NSMutableSet alloc] init]; // should be a hashtable
130 [self->awakeObjects release];
131 [self->unarchivedObjects release];
132 [self->plist release];
138 - (id)decodeObjectForKey:(NSString *)_key {
140 NSDictionary *lastParent;
143 lastParent = self->parent;
144 self->parent = self->plist;
145 self->plist = [(NSDictionary *)self->parent objectForKey:_key];
147 if (![self->plist isKindOfClass:[NSDictionary class]]) {
148 obj = [[self->plist copy] autorelease];
150 else if ((className = [self->plist objectForKey:@"class"]) != nil) {
151 obj = [NSClassFromString(className) alloc];
152 obj = [obj initWithKeyValueUnarchiver:self];
154 [self->unarchivedObjects addObject:obj];
161 self->plist = self->parent;
162 self->parent = lastParent;
166 - (id)decodeObjectReferenceForKey:(NSString *)_key {
169 refObj = [self decodeObjectForKey:_key];
171 if ([self->delegate respondsToSelector:
172 @selector(unarchiver:objectForReference:)]) {
173 obj = [self->delegate unarchiver:self objectForReference:refObj];
175 [self->unarchivedObjects addObject:obj];
178 /* if delegate does not dereference, pass back the reference object */
184 - (BOOL)decodeBoolForKey:(NSString *)_key {
185 return [[self->plist objectForKey:_key] boolValue];
187 - (int)decodeIntForKey:(NSString *)_key {
188 return [[self->plist objectForKey:_key] intValue];
193 - (void)ensureObjectAwake:(id)_object {
194 if (![self->awakeObjects containsObject:_object]) {
195 if ([_object respondsToSelector:@selector(awakeFromKeyValueUnarchiver:)]) {
196 [_object awakeFromKeyValueUnarchiver:self];
198 [self->awakeObjects addObject:_object];
201 - (void)awakeObjects {
205 e = [self->unarchivedObjects objectEnumerator];
206 while ((obj = [e nextObject]))
207 [self ensureObjectAwake:obj];
210 - (void)finishInitializationOfObjects {
214 e = [self->unarchivedObjects objectEnumerator];
215 while ((obj = [e nextObject])) {
216 if ([obj respondsToSelector:
217 @selector(finishInitializationWithKeyValueUnarchiver:)])
218 [obj finishInitializationWithKeyValueUnarchiver:self];
228 - (void)setDelegate:(id)_delegate {
229 self->delegate = _delegate;
232 return self->delegate;
235 @end /* EOKeyValueUnarchiver */