]> err.no Git - sope/blob - sope-ical/versitSaxDriver/VSStringFormatter.m
improved input processing of sax driver
[sope] / sope-ical / versitSaxDriver / VSStringFormatter.m
1 /*
2   Copyright (C) 2004-2005 OpenGroupware.org
3  
4   This file is part of versitSaxDriver, written for the OpenGroupware.org
5   project (OGo).
6  
7   SOPE is free software; you can redistribute it and/or modify it under
8   the terms of the GNU Lesser General Public License as published by the
9   Free Software Foundation; either version 2, or (at your option) any
10   later version.
11  
12   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15   License for more details.
16  
17   You should have received a copy of the GNU Lesser General Public
18   License along with SOPE; see the file COPYING.  If not, write to the
19   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20   02111-1307, USA.
21 */
22
23 #include "VSStringFormatter.h"
24 #include "common.h"
25
26 @implementation VSStringFormatter
27
28 static NSCharacterSet *escSet = nil;
29
30 + (void)initialize {
31   static BOOL didInit = NO;
32   
33   if(didInit)
34     return;
35   
36   didInit = YES;
37   escSet = [[NSCharacterSet characterSetWithCharactersInString:@"\\"] retain];
38 }
39
40 + (id)sharedFormatter {
41   static id sharedInstance = nil;
42   if(!sharedInstance) {
43     sharedInstance = [[self alloc] init];
44   }
45   return sharedInstance;
46 }
47
48 - (NSString *)stringByUnescapingRFC2445Text:(NSString *)_s {
49   NSMutableString *safeString;
50   unsigned        length;
51   NSRange         prevRange, escRange;
52   NSRange         todoRange;
53   BOOL            needsEscaping;
54
55   length    = [_s length];
56   prevRange = NSMakeRange(0, length);
57   escRange  = [_s rangeOfCharacterFromSet:escSet options:0 range:prevRange];
58
59   needsEscaping = escRange.length > 0 ? YES : NO;
60   if (!needsEscaping)
61     return _s; /* cheap */
62   
63   safeString = [NSMutableString stringWithCapacity:length];
64   
65   do {
66     prevRange.length = escRange.location - prevRange.location;
67     if (prevRange.length > 0)
68       [safeString appendString:[_s substringWithRange:prevRange]];
69
70     /* test edge case */
71     if(NSMaxRange(escRange) < length) {
72       unichar c = [_s characterAtIndex:escRange.location + 1];
73       if(c == 'n' || c == 'N') {
74         [safeString appendString:@"\n"];
75         escRange.length += 1; /* skip the 'n' */
76       }
77     }
78     
79     prevRange.location = NSMaxRange(escRange);
80     todoRange.location = prevRange.location;
81     todoRange.length   = length - prevRange.location;
82     escRange           = [_s rangeOfCharacterFromSet:escSet
83                              options:0
84                              range:todoRange];
85   }
86   while(escRange.length > 0);
87   
88   if (todoRange.length > 0)
89     [safeString appendString:[_s substringWithRange:todoRange]];
90   
91   return safeString;
92 }
93
94 @end /* VSStringFormatter */