+2004-10-16 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * v1.0.3
+
+ * VSStringFormatter.[hm]: new singleton to perform unescaping on
+ iCal content/attributes.
+
+ * VSSaxDriver.m: uses the new VSStringFormatter in some funky places.
+ Unescaping is pretty memory efficient, hence its slight overuse is
+ justifyable I guess.
+
2004-10-15 Marcus Mueller <znek@mulle-kybernetik.com>
* GNUmakefile.preamble: NGExtensions was missing for proper inline
VSSaxDriver.m \
VSiCalSaxDriver.m \
VSvCardSaxDriver.m \
+ VSStringFormatter.m \
versitSaxDriver_RESOURCE_FILES = bundle-info.plist
// $Id$
#include "VSSaxDriver.h"
+#include "VSStringFormatter.h"
#include "common.h"
@implementation VSSaxDriver
static NSCharacterSet *colonAndSemicolonCharSet = nil;
static NSCharacterSet *whitespaceCharSet = nil;
+static VSStringFormatter *stringFormatter = nil;
+
+ (void)initialize {
static BOOL didInit = NO;
NSUserDefaults *ud;
[[NSCharacterSet characterSetWithCharactersInString:@":;"] retain];
whitespaceCharSet =
[[NSCharacterSet whitespaceCharacterSet] retain];
+
+ stringFormatter = [VSStringFormatter sharedFormatter];
}
intoAttr:(NSString **)attr_
intoValue:(NSString **)value_
{
- NSRange r;
- NSString *attrName;
- NSMutableString *attrValue;
- NSString *mappedName;
+ NSRange r;
+ NSString *attrName, *attrValue, *mappedName;
r = [_attr rangeOfCharacterFromSet:equalSignCharSet];
if (r.length > 0) {
attrName = [[_attr substringToIndex:r.location] uppercaseString];
- attrValue = [[_attr substringFromIndex:(r.location + 1)] mutableCopy];
+ attrValue = [_attr substringFromIndex:(r.location + 1)];
}
else {
attrName = @"TYPE";
- attrValue = [[NSMutableString alloc] initWithString:_attr];
+ attrValue = _attr;
}
+#if 0
+ // ZNeK: what's this for?
r = [attrValue rangeOfCharacterFromSet:commaCharSet];
while (r.length > 0) {
[attrValue replaceCharactersInRange:r withString:@" "];
r = [attrValue rangeOfCharacterFromSet:commaCharSet];
}
+#endif
mappedName = [self _mapAttrName:attrName forTag:_tagName];
*attr_ = mappedName;
- *value_ = [NSString stringWithString:attrValue];
- [attrValue release];
+ *value_ = [stringFormatter stringByUnescapingRFC2445Text:attrValue];
}
- (id<NSObject,SaxAttributes>)_mapAttrs:(NSArray *)_attrs
andContent:(NSString *)_content
{
NSArray *subItems;
-
+
+ _content = [stringFormatter stringByUnescapingRFC2445Text:_content];
if ([self->attributeElements containsObject:_tagName]) {
[self _addAttribute:_tagName value:_content];
}
--- /dev/null
+/*
+ Copyright (C) 2004 OpenGroupware.org
+
+ This file is part of versitSaxDriver, written for the OpenGroupware.org
+ project (OGo).
+
+ OGo 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.
+
+ OGo 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 OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+ */
+// $Id$
+
+
+#ifndef __VSStringFormatter_H_
+#define __VSStringFormatter_H_
+
+#import <Foundation/Foundation.h>
+
+@interface VSStringFormatter : NSObject
+{
+}
+
++ (id)sharedFormatter;
+- (NSString *)stringByUnescapingRFC2445Text:(NSString *)_s;
+
+@end
+
+#endif /* __VSStringFormatter_H_ */
--- /dev/null
+/*
+ Copyright (C) 2004 OpenGroupware.org
+
+ This file is part of versitSaxDriver, written for the OpenGroupware.org
+ project (OGo).
+
+ OGo 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.
+
+ OGo 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 OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+ */
+// $Id$
+
+
+#include "VSStringFormatter.h"
+#include "common.h"
+
+@implementation VSStringFormatter
+
+static NSCharacterSet *escSet = nil;
+
++ (void)initialize {
+ static BOOL didInit = NO;
+
+ if(didInit)
+ return;
+
+ didInit = YES;
+ escSet = [[NSCharacterSet characterSetWithCharactersInString:@"\\"] retain];
+}
+
++ (id)sharedFormatter {
+ static id sharedInstance = nil;
+ if(!sharedInstance) {
+ sharedInstance = [[self alloc] init];
+ }
+ return sharedInstance;
+}
+
+- (NSString *)stringByUnescapingRFC2445Text:(NSString *)_s {
+ NSMutableString *safeString;
+ unsigned length;
+ NSRange prevRange, escRange;
+ NSRange todoRange;
+ BOOL needsEscaping;
+
+ length = [_s length];
+ prevRange = NSMakeRange(0, length);
+ escRange = [_s rangeOfCharacterFromSet:escSet options:0 range:prevRange];
+
+ needsEscaping = escRange.length > 0 ? YES : NO;
+ if (!needsEscaping)
+ return _s; /* cheap */
+
+ safeString = [NSMutableString stringWithCapacity:length];
+
+ do {
+ prevRange.length = escRange.location - prevRange.location;
+ if (prevRange.length > 0)
+ [safeString appendString:[_s substringWithRange:prevRange]];
+
+ /* test edge case */
+ if(NSMaxRange(escRange) < length) {
+ unichar c = [_s characterAtIndex:escRange.location + 1];
+ if(c == 'n') {
+ [safeString appendString:@"\n"];
+ escRange.length += 1; /* skip the 'n' */
+ }
+ }
+
+ prevRange.location = NSMaxRange(escRange);
+ todoRange.location = prevRange.location;
+ todoRange.length = length - prevRange.location;
+ escRange = [_s rangeOfCharacterFromSet:escSet
+ options:0
+ range:todoRange];
+ }
+ while(escRange.length > 0);
+
+ if (todoRange.length > 0)
+ [safeString appendString:[_s substringWithRange:todoRange]];
+
+ return safeString;
+}
+
+@end
MAJOR_VERSION=1
MINOR_VERSION=0
-SUBMINOR_VERSION:=2
+SUBMINOR_VERSION:=3
1656CD26058806680012D2BC,
1656CD7E058809660012D2BC,
AD665AB6071EB38C00EC5911,
+ AD0CFACC071FFF0000E72147,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
1656CCE5058805BB0012D2BC,
1656CD27058806680012D2BC,
1656CD7F058809660012D2BC,
+ AD0CFACD071FFF0000E72147,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
1656CD25058806680012D2BC,
1656CCE3058805BB0012D2BC,
1656CD7D058809660012D2BC,
+ AD0CFACB071FFF0000E72147,
);
isa = PBXGroup;
name = Classes;
//AD2
//AD3
//AD4
+ AD0CFACA071FFF0000E72147 = {
+ fileEncoding = 5;
+ indentWidth = 2;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.h;
+ path = VSStringFormatter.h;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ AD0CFACB071FFF0000E72147 = {
+ fileEncoding = 5;
+ indentWidth = 2;
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.objc;
+ path = VSStringFormatter.m;
+ refType = 4;
+ sourceTree = "<group>";
+ };
+ AD0CFACC071FFF0000E72147 = {
+ fileRef = AD0CFACA071FFF0000E72147;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ AD0CFACD071FFF0000E72147 = {
+ fileRef = AD0CFACB071FFF0000E72147;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
AD5010A5071F18AE0020300E = {
fileEncoding = 4;
isa = PBXFileReference;
1656CD24058806680012D2BC,
1656CCE2058805BB0012D2BC,
1656CD7C058809660012D2BC,
+ AD0CFACA071FFF0000E72147,
);
isa = PBXGroup;
name = Headers;