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
22 #import "NGCardsSaxHandler.h"
28 #ifndef XMLNS_VCARD_XML_03
29 # define XMLNS_VCARD_XML_03 \
30 @"http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-03.txt"
33 @implementation NGCardsSaxHandler
37 if ((self = [super init]))
49 [currentGroup release];
57 return [[cards copy] autorelease];;
62 - (void)resetExceptResult
71 vcs.collectContent = 0;
76 [self resetExceptResult];
77 [cards removeAllObjects];
82 - (void) startDocument
85 cards = [[NSMutableArray alloc] initWithCapacity:16];
91 [self resetExceptResult];
96 - (void) startValueTag: (NSString *) _tag
97 attributes: (id<SaxAttributes>) _attrs
99 /* a tag with types and attributes */
102 [types removeAllObjects];
103 [args removeAllObjects];
105 for (i = 0, count = [_attrs count]; i < count; i++) {
108 n = [_attrs nameAtIndex:i];
109 v = [_attrs valueAtIndex:i];
111 if ([n hasSuffix:@".type"] || [n isEqualToString:@"TYPE"]) {
113 Note: types cannot be separated by comma! Its indeed always a space,eg
115 If you find commas, usually the vCard is broken.
120 e = [[v componentsSeparatedByString:@" "] objectEnumerator];
121 while ((k = [e nextObject]) != nil) {
122 k = [k uppercaseString];
123 if ([types containsObject:k]) continue;
128 [args setObject:v forKey:n];
134 [types removeAllObjects];
135 [args removeAllObjects];
138 /* handle elements */
140 - (void) startGroup: (NSString *)_name
143 ASSIGNCOPY(currentGroup, _name);
149 [currentGroup release];
153 - (void)startVCardSet
155 currentCardGroup = nil;
157 vcs.isInVCardSet = 1;
162 vcs.isInVCardSet = 0;
167 - (void) startElement:(NSString *)_localName
168 namespace:(NSString *)_ns
169 rawName:(NSString *)_rawName
170 attributes:(id<SaxAttributes>)_attrs
172 unsigned int count, max;
175 // NSLog (@"startElement localName: '%@'", _localName);
177 if ([_localName isEqualToString: @"vCardSet"])
178 [self startVCardSet];
179 else if ([_localName isEqualToString: @"group"])
180 [self startGroup: [_attrs valueAtIndex: 0]];
181 else if ([_localName isEqualToString: @"container"])
182 [self startGroupElement: [_attrs valueAtIndex: 0]];
185 if (currentCardGroup)
187 = [currentCardGroup classForTag: [_localName uppercaseString]];
189 elementClass = topGroupClass;
192 elementClass = [CardElement class];
194 currentElement = [elementClass elementWithTag: _localName];
195 [currentElement setTag: _localName];
197 [currentElement setGroup: currentGroup];
199 max = [_attrs count];
200 for (count = 0; count < max; count++)
201 [currentElement addAttribute: [_attrs nameAtIndex: count]
202 value: [_attrs valueAtIndex: count]];
204 [currentCardGroup addChild: currentElement];
205 [self startCollectingContent];
209 - (void) endElement: (NSString *)_localName
210 namespace: (NSString *)_ns
211 rawName: (NSString *)_rawName
213 // NSLog (@"endElement localName: '%@'", _localName);
214 if ([_localName isEqualToString: @"vCardSet"])
216 else if ([_localName isEqualToString: @"group"])
218 else if ([_localName isEqualToString: @"container"])
219 [self endGroupElement];
221 [currentElement addValues: [self finishCollectingContent]];
226 - (void) startCollectingContent
232 vcs.collectContent = 1;
235 - (NSArray *) finishCollectingContent
237 NSArray *contentValues;
240 vcs.collectContent = 0;
242 if (content && contentLength)
244 s = [NSString stringWithCharacters: content
245 length: contentLength];
248 // NSLog (@"content: '%@'", s);
249 contentValues = [s componentsSeparatedByString: @";"];
254 return contentValues;
257 - (void) characters:(unichar *)_chars
265 contentLength = _len;
266 content = calloc (_len + 1, sizeof(unichar));
267 memcpy (content, _chars, (_len * sizeof(unichar)));
271 /* increase content */
273 realloc (content, (contentLength + _len+2) * sizeof(unichar));
274 memcpy (&(content[contentLength]), _chars,
275 (_len * sizeof(unichar)));
276 contentLength += _len;
278 content[contentLength] = 0;
282 - (void) startGroupElement: (NSString *) _localName
287 // NSLog (@"startGroupElement localName: '%@'", _localName);
289 if (currentCardGroup)
292 = [currentCardGroup classForTag: [_localName uppercaseString]];
294 groupClass = [CardGroup class];
296 newGroup = [groupClass groupWithTag: _localName];
297 [currentCardGroup addChild: newGroup];
302 groupClass = topGroupClass;
304 groupClass = [CardGroup class];
306 newGroup = [groupClass groupWithTag: _localName];
307 [cards addObject: newGroup];
310 currentCardGroup = newGroup;
313 - (void) endGroupElement
315 // NSLog (@"endGroupElement localName: '%@'", _localName);
317 if (currentCardGroup)
318 currentCardGroup = [currentCardGroup parent];
321 - (void) setTopElementClass: (Class) aGroupClass
323 topGroupClass = aGroupClass;
326 @end /* NGCardsSaxHandler */