sogo/SOPE/NGCards/NGCardsSaxHandler.m
Enrique J. Hernández Blasco 2c6d833c11 Remove an attempt to double free content
As content is freed by resetExceptResult message received by reset
which has been called by dealloc as well
2014-11-28 10:04:18 +01:00

304 lines
6.8 KiB
Objective-C

/*
Copyright (C) 2005 Helge Hess
This file is part of SOPE.
SOPE is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with SOPE; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <string.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSString.h>
#import "NSString+NGCards.h"
#import "NGCardsSaxHandler.h"
#import "CardGroup.h"
#ifndef XMLNS_VCARD_XML_03
# define XMLNS_VCARD_XML_03 \
@"http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-03.txt"
#endif
static NSArray *privilegedTagNames = nil;
@implementation NGCardsSaxHandler
- (id) init
{
if ((self = [super init]))
topGroupClass = nil;
if (!privilegedTagNames)
{
privilegedTagNames = [NSArray arrayWithObjects: @"ADR", @"N", @"RRULE", @"ORG", nil];
RETAIN(privilegedTagNames);
}
return self;
}
- (void) dealloc
{
[self reset];
[cards release];
[currentGroup release];
[super dealloc];
}
/* results */
- (NSArray *) cards
{
return [[cards copy] autorelease];
}
/* state */
- (void) resetExceptResult
{
if (content)
{
free (content);
content = NULL;
}
vcs.isInVCardSet = 0;
vcs.isInVCard = 0;
vcs.isInGroup = 0;
vcs.collectContent = 0;
}
- (void) reset
{
[self resetExceptResult];
[cards removeAllObjects];
}
/* document events */
- (void) startDocument
{
if (!cards)
cards = [[NSMutableArray alloc] initWithCapacity: 16];
[self reset];
}
- (void) endDocument
{
[self resetExceptResult];
}
/* handle elements */
- (void) startGroup: (NSString *)_name
{
vcs.isInGroup = 1;
ASSIGNCOPY (currentGroup, _name);
}
- (void) endGroup
{
vcs.isInGroup = 0;
[currentGroup release];
currentGroup = nil;
}
- (void) startVCardSet
{
currentCardGroup = nil;
currentGroup = nil;
vcs.isInVCardSet = 1;
}
- (void) endVCardSet
{
vcs.isInVCardSet = 0;
}
/* element events */
- (void) startElement:(NSString *)_localName
namespace:(NSString *)_ns
rawName:(NSString *)_rawName
attributes:(id<SaxAttributes>)_attrs
{
unsigned int count, max;
Class elementClass;
// NSLog (@"startElement localName: '%@'", _localName);
if ([_localName isEqualToString: @"vCardSet"])
[self startVCardSet];
else if ([_localName isEqualToString: @"group"])
[self startGroup: [_attrs valueAtIndex: 0]];
else if ([_localName isEqualToString: @"container"])
[self startGroupElement: [_attrs valueAtIndex: 0]];
else
{
if (currentCardGroup)
elementClass
= [currentCardGroup classForTag: [_localName uppercaseString]];
else
elementClass = topGroupClass;
if (!elementClass)
elementClass = [CardElement class];
currentElement = [elementClass elementWithTag: _localName];
[currentElement setTag: _localName];
if (currentGroup)
[currentElement setGroup: currentGroup];
max = [_attrs count];
for (count = 0; count < max; count++)
[currentElement addAttribute: [_attrs nameAtIndex: count]
value: [_attrs valueAtIndex: count]];
[currentCardGroup addChild: currentElement];
[self startCollectingContent];
}
}
- (void) endElement: (NSString *)_localName
namespace: (NSString *)_ns
rawName: (NSString *)_rawName
{
// NSLog (@"endElement localName: '%@'", _localName);
if ([_localName isEqualToString: @"vCardSet"])
[self endVCardSet];
else if ([_localName isEqualToString: @"group"])
[self endGroup];
else if ([_localName isEqualToString: @"container"])
[self endGroupElement];
else
[currentElement setValues: [self finishCollectingContent]];
}
/* content */
- (void) startCollectingContent
{
if (content)
{
free (content);
content = NULL;
}
vcs.collectContent = 1;
}
- (NSMutableDictionary *) finishCollectingContent
{
NSMutableDictionary *contentValues;
NSString *s;
vcs.collectContent = 0;
if (content && contentLength)
{
s = [NSString stringWithCharacters: content
length: contentLength];
free (content);
content = NULL;
//NSLog(@"content: '%@'", s);
if ([privilegedTagNames containsObject: [currentElement tag]])
contentValues = [s vCardSubvalues];
else
contentValues = [NSMutableDictionary dictionaryWithObject: [NSMutableArray arrayWithObject: [s asCardAttributeValues]]
forKey: @""];
}
else
contentValues = nil;
return contentValues;
}
- (void) characters: (unichar *) _chars
length: (NSUInteger) _len
{
if (_len && _chars)
{
if (!content)
{
/* first content */
contentLength = _len;
content = NSZoneMalloc (NULL, (_len + 1) * sizeof (unichar));
memcpy (content, _chars, (_len * sizeof (unichar)));
*(content + _len) = 0;
}
else
{
/* increase content */
content =
NSZoneRealloc (NULL, content,
(contentLength + _len+2) * sizeof(unichar));
memcpy (&(content[contentLength]), _chars,
(_len * sizeof(unichar)));
contentLength += _len;
}
content[contentLength] = 0;
}
}
- (void) startGroupElement: (NSString *) _localName
{
CardGroup *newGroup;
Class groupClass;
// NSLog (@"startGroupElement localName: '%@'", _localName);
if (currentCardGroup)
{
groupClass
= [currentCardGroup classForTag: [_localName uppercaseString]];
if (!groupClass)
groupClass = [CardGroup class];
newGroup = [groupClass groupWithTag: _localName];
[currentCardGroup addChild: newGroup];
}
else
{
if (topGroupClass)
groupClass = topGroupClass;
else
groupClass = [CardGroup class];
newGroup = [groupClass groupWithTag: _localName];
[cards addObject: newGroup];
}
currentCardGroup = newGroup;
}
- (void) endGroupElement
{
// NSLog (@"endGroupElement localName: '%@'", _localName);
if (currentCardGroup)
currentCardGroup = [currentCardGroup parent];
}
- (void) setTopElementClass: (Class) aGroupClass
{
topGroupClass = aGroupClass;
}
@end /* NGCardsSaxHandler */