2 Copyright (C) 2005 Helge Hess
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
23 #import <Foundation/NSArray.h>
25 #import "NGCardsSaxHandler.h"
29 #ifndef XMLNS_VCARD_XML_03
30 # define XMLNS_VCARD_XML_03 \
31 @"http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-03.txt"
34 @implementation NGCardsSaxHandler
38 if ((self = [super init]))
50 [currentGroup release];
58 return [[cards copy] autorelease];;
63 - (void)resetExceptResult
72 vcs.collectContent = 0;
77 [self resetExceptResult];
78 [cards removeAllObjects];
83 - (void) startDocument
86 cards = [[NSMutableArray alloc] initWithCapacity:16];
92 [self resetExceptResult];
97 - (void) startValueTag: (NSString *) _tag
98 attributes: (id<SaxAttributes>) _attrs
100 /* a tag with types and attributes */
103 [types removeAllObjects];
104 [args removeAllObjects];
106 for (i = 0, count = [_attrs count]; i < count; i++) {
109 n = [_attrs nameAtIndex:i];
110 v = [_attrs valueAtIndex:i];
112 if ([n hasSuffix:@".type"] || [n isEqualToString:@"TYPE"]) {
114 Note: types cannot be separated by comma! Its indeed always a space,eg
116 If you find commas, usually the vCard is broken.
121 e = [[v componentsSeparatedByString:@" "] objectEnumerator];
122 while ((k = [e nextObject]) != nil) {
123 k = [k uppercaseString];
124 if ([types containsObject:k]) continue;
129 [args setObject:v forKey:n];
135 [types removeAllObjects];
136 [args removeAllObjects];
139 /* handle elements */
141 - (void) startGroup: (NSString *)_name
144 ASSIGNCOPY(currentGroup, _name);
150 [currentGroup release];
154 - (void)startVCardSet
156 currentCardGroup = nil;
158 vcs.isInVCardSet = 1;
163 vcs.isInVCardSet = 0;
168 - (void) startElement:(NSString *)_localName
169 namespace:(NSString *)_ns
170 rawName:(NSString *)_rawName
171 attributes:(id<SaxAttributes>)_attrs
173 unsigned int count, max;
176 // NSLog (@"startElement localName: '%@'", _localName);
178 if ([_localName isEqualToString: @"vCardSet"])
179 [self startVCardSet];
180 else if ([_localName isEqualToString: @"group"])
181 [self startGroup: [_attrs valueAtIndex: 0]];
182 else if ([_localName isEqualToString: @"container"])
183 [self startGroupElement: [_attrs valueAtIndex: 0]];
186 if (currentCardGroup)
188 = [currentCardGroup classForTag: [_localName uppercaseString]];
190 elementClass = topGroupClass;
193 elementClass = [CardElement class];
195 currentElement = [elementClass elementWithTag: _localName];
196 [currentElement setTag: _localName];
198 [currentElement setGroup: currentGroup];
200 max = [_attrs count];
201 for (count = 0; count < max; count++)
202 [currentElement addAttribute: [_attrs nameAtIndex: count]
203 value: [_attrs valueAtIndex: count]];
205 [currentCardGroup addChild: currentElement];
206 [self startCollectingContent];
210 - (void) endElement: (NSString *)_localName
211 namespace: (NSString *)_ns
212 rawName: (NSString *)_rawName
214 // NSLog (@"endElement localName: '%@'", _localName);
215 if ([_localName isEqualToString: @"vCardSet"])
217 else if ([_localName isEqualToString: @"group"])
219 else if ([_localName isEqualToString: @"container"])
220 [self endGroupElement];
222 [currentElement addValues: [self finishCollectingContent]];
227 - (void) startCollectingContent
233 vcs.collectContent = 1;
236 - (NSArray *) finishCollectingContent
238 NSArray *contentValues;
241 vcs.collectContent = 0;
243 if (content && contentLength)
245 s = [NSString stringWithCharacters: content
246 length: contentLength];
249 // NSLog (@"content: '%@'", s);
250 contentValues = [s componentsSeparatedByString: @";"];
255 return contentValues;
258 - (void) characters:(unichar *)_chars
266 contentLength = _len;
267 content = calloc (_len + 1, sizeof(unichar));
268 memcpy (content, _chars, (_len * sizeof(unichar)));
272 /* increase content */
274 realloc (content, (contentLength + _len+2) * sizeof(unichar));
275 memcpy (&(content[contentLength]), _chars,
276 (_len * sizeof(unichar)));
277 contentLength += _len;
279 content[contentLength] = 0;
283 - (void) startGroupElement: (NSString *) _localName
288 // NSLog (@"startGroupElement localName: '%@'", _localName);
290 if (currentCardGroup)
293 = [currentCardGroup classForTag: [_localName uppercaseString]];
295 groupClass = [CardGroup class];
297 newGroup = [groupClass groupWithTag: _localName];
298 [currentCardGroup addChild: newGroup];
303 groupClass = topGroupClass;
305 groupClass = [CardGroup class];
307 newGroup = [groupClass groupWithTag: _localName];
308 [cards addObject: newGroup];
311 currentCardGroup = newGroup;
314 - (void) endGroupElement
316 // NSLog (@"endGroupElement localName: '%@'", _localName);
318 if (currentCardGroup)
319 currentCardGroup = [currentCardGroup parent];
322 - (void) setTopElementClass: (Class) aGroupClass
324 topGroupClass = aGroupClass;
327 @end /* NGCardsSaxHandler */