]> err.no Git - sope/commitdiff
proper unescaping
authorznek <znek@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sat, 16 Oct 2004 16:57:07 +0000 (16:57 +0000)
committerznek <znek@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sat, 16 Oct 2004 16:57:07 +0000 (16:57 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@265 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-ical/versitSaxDriver/ChangeLog
sope-ical/versitSaxDriver/GNUmakefile
sope-ical/versitSaxDriver/VSSaxDriver.m
sope-ical/versitSaxDriver/VSStringFormatter.h [new file with mode: 0644]
sope-ical/versitSaxDriver/VSStringFormatter.m [new file with mode: 0644]
sope-ical/versitSaxDriver/Version
sope-ical/versitSaxDriver/versitSaxDriver.xcode/project.pbxproj

index 8bb49518bd2d885b8ff1bed4ca54f42908d12add..6d51a38162cc6969dddbd584945b83950b041843 100644 (file)
@@ -1,3 +1,14 @@
+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
index 21ac77c9362bb144b6b203d9554c61221d5837a1..262f220a012ef258498b6c8cebea1603fa5a1d74 100644 (file)
@@ -10,6 +10,7 @@ versitSaxDriver_OBJC_FILES =  \
        VSSaxDriver.m           \
        VSiCalSaxDriver.m       \
        VSvCardSaxDriver.m      \
+       VSStringFormatter.m     \
 
 versitSaxDriver_RESOURCE_FILES = bundle-info.plist
 
index d0922f19c13f3296a6d0b6955509f0386e3a808b..db359f995376f0d6ae5afa899c120210f3d9a065 100644 (file)
@@ -23,6 +23,7 @@
 // $Id$
 
 #include "VSSaxDriver.h"
+#include "VSStringFormatter.h"
 #include "common.h"
 
 @implementation VSSaxDriver
@@ -35,6 +36,8 @@ static NSCharacterSet *commaCharSet = nil;
 static NSCharacterSet *colonAndSemicolonCharSet = nil;
 static NSCharacterSet *whitespaceCharSet = nil;
 
+static VSStringFormatter *stringFormatter = nil;
+
 + (void)initialize {
   static BOOL didInit = NO;
   NSUserDefaults *ud;
@@ -56,6 +59,8 @@ static NSCharacterSet *whitespaceCharSet = nil;
     [[NSCharacterSet characterSetWithCharactersInString:@":;"] retain];
   whitespaceCharSet =
     [[NSCharacterSet whitespaceCharacterSet] retain];
+
+  stringFormatter = [VSStringFormatter sharedFormatter];
 }
 
 
@@ -235,31 +240,31 @@ static NSCharacterSet *whitespaceCharSet = nil;
   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 
@@ -340,7 +345,8 @@ static NSCharacterSet *whitespaceCharSet = nil;
   andContent:(NSString *)_content 
 {
   NSArray *subItems;
-  
+
+  _content = [stringFormatter stringByUnescapingRFC2445Text:_content];
   if ([self->attributeElements containsObject:_tagName]) {
     [self _addAttribute:_tagName value:_content];
   } 
diff --git a/sope-ical/versitSaxDriver/VSStringFormatter.h b/sope-ical/versitSaxDriver/VSStringFormatter.h
new file mode 100644 (file)
index 0000000..b15f7c6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ 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_ */
diff --git a/sope-ical/versitSaxDriver/VSStringFormatter.m b/sope-ical/versitSaxDriver/VSStringFormatter.m
new file mode 100644 (file)
index 0000000..ae2de6e
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ 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
index e3d970fc7d39b78efb63bf03d1c24e6e6b6aedf4..99d4ed2737331c80b62c12f78abac8bd61c1325f 100644 (file)
@@ -2,4 +2,4 @@
 
 MAJOR_VERSION=1
 MINOR_VERSION=0
-SUBMINOR_VERSION:=2
+SUBMINOR_VERSION:=3
index 0b1b600eebf6caaa4407ef6e038ffe27e6744259..7ed06d4440acd347a6dae71e717f28e97d950ea7 100644 (file)
@@ -68,6 +68,7 @@
                                1656CD26058806680012D2BC,
                                1656CD7E058809660012D2BC,
                                AD665AB6071EB38C00EC5911,
+                               AD0CFACC071FFF0000E72147,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
@@ -92,6 +93,7 @@
                                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;