]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/NSString+NGCards.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1018 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   NSString *newString;
46   NSMutableString *foldedString;
47   unsigned int length;
48   NSRange subStringRange;
49
50   length = [self length];
51   if (length < 76)
52     newString = self;
53   else
54     {
55       foldedString = [NSMutableString new];
56       [foldedString autorelease];
57
58       subStringRange = NSMakeRange (0, 75);
59       [foldedString appendFormat: @"%@\r\n",
60                     [self substringWithRange: subStringRange]];
61       subStringRange = NSMakeRange (75, 74);
62       while ((length - subStringRange.location) > 74)
63         {
64           [foldedString appendFormat: @" %@\r\n",
65                         [self substringWithRange: subStringRange]];
66           subStringRange.location += 74;
67         }
68       subStringRange.length = length - subStringRange.location;
69       [foldedString appendFormat: @" %@",
70                     [self substringWithRange: subStringRange]];
71
72       newString = foldedString;
73     }
74
75   return newString;
76 }
77
78 - (NSArray *) asCardAttributeValues
79 {
80   NSMutableArray *values;
81   NSEnumerator *rawValues;
82   NSString *tmpString, *rawValue, *newString;
83
84   values = [NSMutableArray new];
85   [values autorelease];
86
87   if (!commaSeparator)
88     [self _initCommaSeparator];
89
90   tmpString = [self stringByReplacingString: @"\\,"
91                     withString: commaSeparator];
92   rawValues = [[tmpString componentsSeparatedByString: @","]
93                 objectEnumerator];
94   rawValue = [rawValues nextObject];
95   while (rawValue)
96     {
97       newString = [rawValue stringByReplacingString: commaSeparator
98                             withString: @","];
99       [values addObject: [newString stringByTrimmingSpaces]];
100       rawValue = [rawValues nextObject];
101     }
102
103   return values;
104 }
105
106 - (NSString *) escapedForCards
107 {
108   NSString *string;
109
110   string = [self stringByReplacingString: @"\\"
111                  withString: @"\\\\"];
112   string = [string stringByReplacingString: @","
113                    withString: @"\\,"];
114 //   string = [string stringByReplacingString: @":"
115 //                    withString: @"\\:"];
116   string = [string stringByReplacingString: @";"
117                    withString: @"\\;"];
118   string = [string stringByReplacingString: @"\n"
119                    withString: @"\\n"];
120   string = [string stringByReplacingString: @"\r"
121                    withString: @"\\r"];
122
123   return string;
124 }
125
126 - (NSString *) unescapedFromCard
127 {
128   NSString *string;
129
130   string = [self stringByReplacingString: @"\\,"
131                  withString: @","];
132   string = [string stringByReplacingString: @"\\:"
133                    withString: @":"];
134   string = [string stringByReplacingString: @"\\;"
135                    withString: @";"];
136   string = [string stringByReplacingString: @"\\n"
137                    withString: @"\n"];
138   string = [string stringByReplacingString: @"\\r"
139                    withString: @"\r"];
140   string = [string stringByReplacingString: @"\\\\"
141                    withString: @"\\"];
142
143   return string;
144 }
145
146 - (NSTimeInterval) durationAsTimeInterval
147 {
148   /*
149     eg: DURATION:PT1H
150     P      - "period"
151     P2H30M - "2 hours 30 minutes"
152
153      dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
154
155      dur-date   = dur-day [dur-time]
156      dur-time   = "T" (dur-hour / dur-minute / dur-second)
157      dur-week   = 1*DIGIT "W"
158      dur-hour   = 1*DIGIT "H" [dur-minute]
159      dur-minute = 1*DIGIT "M" [dur-second]
160      dur-second = 1*DIGIT "S"
161      dur-day    = 1*DIGIT "D"
162   */
163   unsigned       i, len;
164   NSTimeInterval ti;
165   BOOL           isTime;
166   int            val;
167     
168   if (![self hasPrefix:@"P"]) {
169     NSLog(@"Cannot parse iCal duration value: '%@'", self);
170     return 0.0;
171   }
172     
173   ti  = 0.0;
174   val = 0;
175   for (i = 1, len = [self length], isTime = NO; i < len; i++) {
176     unichar c;
177       
178     c = [self characterAtIndex:i];
179     if (c == 't' || c == 'T') {
180       isTime = YES;
181       val = 0;
182       continue;
183     }
184       
185     if (isdigit(c)) {
186       val = (val * 10) + (c - 48);
187       continue;
188     }
189       
190     switch (c) {
191     case 'W': /* week */
192       ti += (val * 7 * 24 * 60 * 60);
193       break;
194     case 'D': /* day  */
195       ti += (val * 24 * 60 * 60);
196       break;
197     case 'H': /* hour */
198       ti += (val * 60 * 60);
199       break;
200     case 'M': /* min  */
201       ti += (val * 60);
202       break;
203     case 'S': /* sec  */
204       ti += val;
205       break;
206     default:
207       [self logWithFormat: @"cannot process duration unit: '%c'", c];
208       break;
209     }
210     val = 0;
211   }
212   return ti;
213 }
214
215 - (NSCalendarDate *) asCalendarDate
216 {
217   NSRange cursor;
218   NSCalendarDate *date;
219   NSTimeZone *utc;
220   int year, month, day, hour, minute, second;
221
222   if ([self length] > 14)
223     {
224       cursor = NSMakeRange(0, 4);
225       year = [[self substringWithRange: cursor] intValue];
226       cursor.location += cursor.length;
227       cursor.length = 2;
228       month = [[self substringWithRange: cursor] intValue];
229       cursor.location += cursor.length;
230       day = [[self substringWithRange: cursor] intValue];
231
232       cursor.location += cursor.length + 1;
233       hour = [[self substringWithRange: cursor] intValue];
234       cursor.location += cursor.length;
235       minute = [[self substringWithRange: cursor] intValue];
236       cursor.location += cursor.length;
237       second = [[self substringWithRange: cursor] intValue];
238
239       utc = [NSTimeZone timeZoneWithAbbreviation: @"GMT"];
240       date = [NSCalendarDate dateWithYear: year month: month 
241                              day: day hour: hour minute: minute 
242                              second: second
243                              timeZone: utc];
244     }
245   else
246     date = nil;
247
248   return date;
249 }
250
251 - (NSArray *) commaSeparatedValues
252 {
253   NSEnumerator *rawValues;
254   NSMutableArray *values;
255   NSString *currentValue, *newValue;
256
257   values = [NSMutableArray new];
258   [values autorelease];
259
260   rawValues = [[self componentsSeparatedByString: @","] objectEnumerator];
261   currentValue = [rawValues nextObject];
262   while (currentValue)
263     {
264       newValue = [currentValue stringByTrimmingSpaces];
265       if ([newValue length])
266         [values addObject: newValue];
267       currentValue = [rawValues nextObject];
268     }
269
270   return values;
271 }
272
273 @end