]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/NSString+NGCards.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1178 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SOPE / NGCards / NSString+NGCards.m
1 /* NSString+NGCards.m - this file is part of SOPE
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSCalendarDate.h>
25 #import <Foundation/NSRange.h>
26 #import <Foundation/NSTimeZone.h>
27 #import <NGExtensions/NSObject+Logs.h>
28
29 #import <ctype.h>
30
31 #import "NSString+NGCards.h"
32
33 static NSString *commaSeparator = nil;
34
35 @implementation NSString (NGCardsExtensions)
36
37 - (void) _initCommaSeparator
38 {
39   commaSeparator = [NSMutableString stringWithFormat: @"%c", 255];
40   [commaSeparator retain];
41 }
42
43 - (NSString *) foldedForVersitCards
44 {
45   NSMutableString *foldedString;
46   unsigned int length;
47   NSRange subStringRange;
48
49   foldedString = [NSMutableString new];
50   [foldedString autorelease];
51
52   length = [self length];
53   if (length < 76)
54     [foldedString appendString: self];
55   else
56     {
57       subStringRange = NSMakeRange (0, 75);
58       [foldedString appendFormat: @"%@\r\n",
59                     [self substringWithRange: subStringRange]];
60       subStringRange = NSMakeRange (75, 74);
61       while ((length - subStringRange.location) > 74)
62         {
63           [foldedString appendFormat: @" %@\r\n",
64                         [self substringWithRange: subStringRange]];
65           subStringRange.location += 74;
66         }
67       subStringRange.length = length - subStringRange.location;
68       [foldedString appendFormat: @" %@",
69                     [self substringWithRange: subStringRange]];
70     }
71
72   return foldedString;
73 }
74
75 - (NSArray *) asCardAttributeValues
76 {
77   NSMutableArray *values;
78   NSEnumerator *rawValues;
79   NSString *tmpString, *rawValue, *newString;
80
81   values = [NSMutableArray new];
82   [values autorelease];
83
84   if (!commaSeparator)
85     [self _initCommaSeparator];
86
87   tmpString = [self stringByReplacingString: @"\\,"
88                     withString: commaSeparator];
89   rawValues = [[tmpString componentsSeparatedByString: @","]
90                 objectEnumerator];
91   rawValue = [rawValues nextObject];
92   while (rawValue)
93     {
94       newString = [rawValue stringByReplacingString: commaSeparator
95                             withString: @","];
96       [values addObject: [newString stringByTrimmingSpaces]];
97       rawValue = [rawValues nextObject];
98     }
99
100   return values;
101 }
102
103 - (NSString *) escapedForCards
104 {
105   NSString *string;
106
107   string = [self stringByReplacingString: @"\\"
108                  withString: @"\\\\"];
109   string = [string stringByReplacingString: @","
110                    withString: @"\\,"];
111 //   string = [string stringByReplacingString: @":"
112 //                    withString: @"\\:"];
113   string = [string stringByReplacingString: @";"
114                    withString: @"\\;"];
115   string = [string stringByReplacingString: @"\n"
116                    withString: @"\\n"];
117   string = [string stringByReplacingString: @"\r"
118                    withString: @"\\r"];
119
120   return string;
121 }
122
123 - (NSString *) unescapedFromCard
124 {
125   NSString *string;
126
127   string = [self stringByReplacingString: @"\\,"
128                  withString: @","];
129   string = [string stringByReplacingString: @"\\:"
130                    withString: @":"];
131   string = [string stringByReplacingString: @"\\;"
132                    withString: @";"];
133   string = [string stringByReplacingString: @"\\n"
134                    withString: @"\n"];
135   string = [string stringByReplacingString: @"\\r"
136                    withString: @"\r"];
137   string = [string stringByReplacingString: @"\\\\"
138                    withString: @"\\"];
139
140   return string;
141 }
142
143 - (NSTimeInterval) durationAsTimeInterval
144 {
145   /*
146     eg: DURATION:PT1H
147     P      - "period"
148     P2H30M - "2 hours 30 minutes"
149
150      dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
151
152      dur-date   = dur-day [dur-time]
153      dur-time   = "T" (dur-hour / dur-minute / dur-second)
154      dur-week   = 1*DIGIT "W"
155      dur-hour   = 1*DIGIT "H" [dur-minute]
156      dur-minute = 1*DIGIT "M" [dur-second]
157      dur-second = 1*DIGIT "S"
158      dur-day    = 1*DIGIT "D"
159   */
160   unsigned       i, len;
161   NSTimeInterval ti;
162   BOOL           isTime;
163   int            val;
164     
165   if (![self hasPrefix:@"P"]) {
166     NSLog(@"Cannot parse iCal duration value: '%@'", self);
167     return 0.0;
168   }
169     
170   ti  = 0.0;
171   val = 0;
172   for (i = 1, len = [self length], isTime = NO; i < len; i++) {
173     unichar c;
174       
175     c = [self characterAtIndex:i];
176     if (c == 't' || c == 'T') {
177       isTime = YES;
178       val = 0;
179       continue;
180     }
181       
182     if (isdigit(c)) {
183       val = (val * 10) + (c - 48);
184       continue;
185     }
186       
187     switch (c) {
188     case 'W': /* week */
189       ti += (val * 7 * 24 * 60 * 60);
190       break;
191     case 'D': /* day  */
192       ti += (val * 24 * 60 * 60);
193       break;
194     case 'H': /* hour */
195       ti += (val * 60 * 60);
196       break;
197     case 'M': /* min  */
198       ti += (val * 60);
199       break;
200     case 'S': /* sec  */
201       ti += val;
202       break;
203     default:
204       [self logWithFormat: @"cannot process duration unit: '%c'", c];
205       break;
206     }
207     val = 0;
208   }
209   return ti;
210 }
211
212 - (NSCalendarDate *) asCalendarDate
213 {
214   NSRange cursor;
215   NSCalendarDate *date;
216   NSTimeZone *utc;
217   unsigned int length;
218   int year, month, day, hour, minute, second;
219
220   length = [self length];
221   if (length > 7)
222     {
223       cursor = NSMakeRange(0, 4);
224       year = [[self substringWithRange: cursor] intValue];
225       cursor.location += cursor.length;
226       cursor.length = 2;
227       month = [[self substringWithRange: cursor] intValue];
228       cursor.location += cursor.length;
229       day = [[self substringWithRange: cursor] intValue];
230
231       if (length > 14)
232         {
233           cursor.location += cursor.length + 1;
234           hour = [[self substringWithRange: cursor] intValue];
235           cursor.location += cursor.length;
236           minute = [[self substringWithRange: cursor] intValue];
237           cursor.location += cursor.length;
238           second = [[self substringWithRange: cursor] intValue];
239         }
240       else
241         {
242           hour = 0;
243           minute = 0;
244           second = 0;
245         }
246
247       utc = [NSTimeZone timeZoneWithAbbreviation: @"GMT"];
248       date = [NSCalendarDate dateWithYear: year month: month 
249                              day: day hour: hour minute: minute 
250                              second: second
251                              timeZone: utc];
252     }
253   else
254     date = nil;
255
256   return date;
257 }
258
259 - (BOOL) isAllDayDate
260 {
261   return ([self length] == 8);
262 }
263
264 - (NSArray *) commaSeparatedValues
265 {
266   NSEnumerator *rawValues;
267   NSMutableArray *values;
268   NSString *currentValue, *newValue;
269
270   values = [NSMutableArray new];
271   [values autorelease];
272
273   rawValues = [[self componentsSeparatedByString: @","] objectEnumerator];
274   currentValue = [rawValues nextObject];
275   while (currentValue)
276     {
277       newValue = [currentValue stringByTrimmingSpaces];
278       if ([newValue length])
279         [values addObject: newValue];
280       currentValue = [rawValues nextObject];
281     }
282
283   return values;
284 }
285
286 @end