]> err.no Git - sope/blob - sope-ical/versitSaxDriver/VSStringFormatter.m
various bugfixes and optimizations
[sope] / sope-ical / versitSaxDriver / VSStringFormatter.m
1 /*
2  Copyright (C) 2004 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
24 #include "VSStringFormatter.h"
25 #include "common.h"
26
27 @implementation VSStringFormatter
28
29 static NSCharacterSet *escSet = nil;
30
31 + (void)initialize {
32   static BOOL didInit = NO;
33   
34   if(didInit)
35     return;
36   
37   didInit = YES;
38   escSet = [[NSCharacterSet characterSetWithCharactersInString:@"\\"] retain];
39 }
40
41 + (id)sharedFormatter {
42   static id sharedInstance = nil;
43   if(!sharedInstance) {
44     sharedInstance = [[self alloc] init];
45   }
46   return sharedInstance;
47 }
48
49 - (NSString *)stringByUnescapingRFC2445Text:(NSString *)_s {
50   NSMutableString *safeString;
51   unsigned        length;
52   NSRange         prevRange, escRange;
53   NSRange         todoRange;
54   BOOL            needsEscaping;
55
56   length    = [_s length];
57   prevRange = NSMakeRange(0, length);
58   escRange  = [_s rangeOfCharacterFromSet:escSet options:0 range:prevRange];
59
60   needsEscaping = escRange.length > 0 ? YES : NO;
61   if (!needsEscaping)
62     return _s; /* cheap */
63   
64   safeString = [NSMutableString stringWithCapacity:length];
65   
66   do {
67     prevRange.length = escRange.location - prevRange.location;
68     if (prevRange.length > 0)
69       [safeString appendString:[_s substringWithRange:prevRange]];
70
71     /* test edge case */
72     if(NSMaxRange(escRange) < length) {
73       unichar c = [_s characterAtIndex:escRange.location + 1];
74       if(c == 'n' || c == 'N') {
75         [safeString appendString:@"\n"];
76         escRange.length += 1; /* skip the 'n' */
77       }
78     }
79     
80     prevRange.location = NSMaxRange(escRange);
81     todoRange.location = prevRange.location;
82     todoRange.length   = length - prevRange.location;
83     escRange           = [_s rangeOfCharacterFromSet:escSet
84                              options:0
85                              range:todoRange];
86   }
87   while(escRange.length > 0);
88   
89   if (todoRange.length > 0)
90     [safeString appendString:[_s substringWithRange:todoRange]];
91   
92   return safeString;
93 }
94
95 @end