]> err.no Git - scalable-opengroupware.org/blob - SoObjects/SOGo/NSString+Utilities.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1101 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / SOGo / NSString+Utilities.m
1 /* NSString+Utilities.m - this file is part of SOGo
2  *
3  * Copyright (C) 2006  Inverse group 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/NSCharacterSet.h>
25 #import <Foundation/NSEnumerator.h>
26
27 #import "NSArray+Utilities.h"
28 #import "NSDictionary+URL.h"
29
30 #import "NSString+Utilities.h"
31
32 static NSMutableCharacterSet *urlNonEndingChars = nil;
33 static NSMutableCharacterSet *urlAfterEndingChars = nil;
34
35 @implementation NSString (SOGoURLExtension)
36
37 - (NSString *) composeURLWithAction: (NSString *) action
38                          parameters: (NSDictionary *) urlParameters
39                             andHash: (BOOL) useHash
40 {
41   NSMutableString *completeURL;
42
43   completeURL = [NSMutableString new];
44   [completeURL autorelease];
45
46   [completeURL appendString: [self urlWithoutParameters]];
47   if (![completeURL hasSuffix: @"/"])
48     [completeURL appendString: @"/"];
49   [completeURL appendString: action];
50   [completeURL appendString: [urlParameters asURLParameters]];
51   if (useHash)
52     [completeURL appendString: @"#"];
53
54   return completeURL;
55 }
56
57 - (NSString *) hostlessURL
58 {
59   NSString *newURL;
60   NSRange hostR, locationR;
61
62   if ([self hasPrefix: @"/"])
63     {
64       newURL = [self copy];
65       [newURL autorelease];
66     }
67   else
68     {
69       hostR = [self rangeOfString: @"://"];
70       locationR = [[self substringFromIndex: (hostR.location + hostR.length)]
71                     rangeOfString: @"/"];
72       newURL = [self substringFromIndex: (hostR.location + hostR.length
73                                           + locationR.location)];
74     }
75
76   return newURL;
77 }
78
79 - (NSString *) urlWithoutParameters;
80 {
81   NSRange r;
82   NSString *newUrl;
83   
84   r = [self rangeOfString:@"?" options: NSBackwardsSearch];
85   if (r.length > 0)
86     newUrl = [self substringToIndex: NSMaxRange(r) - 1];
87   else
88     newUrl = self;
89
90   return newUrl;
91 }
92
93 - (NSString *) davMethodToObjC
94 {
95   NSMutableString *newName;
96   NSEnumerator *components;
97   NSString *component;
98
99   newName = [NSMutableString stringWithString: @"dav"];
100   components = [[self componentsSeparatedByString: @"-"] objectEnumerator];
101   component = [components nextObject];
102   while (component)
103     {
104       [newName appendString: [component capitalizedString]];
105       component = [components nextObject];
106     }
107
108   return newName;
109 }
110
111 - (NSRange) _rangeOfURLInRange: (NSRange) refRange
112 {
113   int start, length;
114   NSRange workRange;
115
116   if (!urlNonEndingChars)
117     {
118       urlNonEndingChars = [NSMutableCharacterSet new];
119       [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"];
120     }
121   if (!urlAfterEndingChars)
122     {
123       urlAfterEndingChars = [NSMutableCharacterSet new];
124       [urlAfterEndingChars addCharactersInString: @"()[]{}&;<\t \r\n"];
125     }
126
127   start = refRange.location;
128   while (start > -1
129          && ![urlAfterEndingChars characterIsMember:
130                                     [self characterAtIndex: start]])
131     start--;
132   start++;
133   length = [self length] - start;
134   workRange = NSMakeRange (start, length);
135   workRange = [self rangeOfCharacterFromSet: urlAfterEndingChars
136                     options: NSLiteralSearch range: workRange];
137   if (workRange.location != NSNotFound)
138     length = workRange.location - start;
139   while
140     (length > 0
141      && [urlNonEndingChars characterIsMember:
142                              [self characterAtIndex: (start + length - 1)]])
143     length--;
144
145   return NSMakeRange (start, length);
146 }
147
148 - (void) _handleURLs: (NSMutableString *) selfCopy
149          textToMatch: (NSString *) match
150               prefix: (NSString *) prefix
151             inRanges: (NSMutableArray *) ranges
152 {
153   NSRange httpRange, currentURL, rest;
154   NSString *urlText, *newUrlText;
155   unsigned int length, matchLength;
156
157   matchLength = [match length];
158   httpRange = [selfCopy rangeOfString: match];
159   while (httpRange.location != NSNotFound)
160     {
161       if ([ranges hasRangeIntersection: httpRange])
162         rest.location = NSMaxRange (httpRange);
163       else
164         {
165           currentURL = [selfCopy _rangeOfURLInRange: httpRange];
166           urlText = [selfCopy substringFromRange: currentURL];
167           if ([urlText length] > matchLength)
168             {
169               newUrlText = [NSString stringWithFormat: @"<a href=\"%@%@\">%@</a>",
170                                      prefix, urlText, urlText];
171               [selfCopy replaceCharactersInRange: currentURL
172                         withString: newUrlText];
173               currentURL
174                 = NSMakeRange (currentURL.location, [newUrlText length]);
175               [ranges addRange: currentURL];
176             }
177           rest.location = NSMaxRange (currentURL);
178         }
179       length = [selfCopy length];
180       rest.length = length - rest.location;
181       httpRange = [selfCopy rangeOfString: match
182                             options: 0 range: rest];
183     }
184 }
185
186 - (NSString *) stringByDetectingURLs
187 {
188   NSMutableString *selfCopy;
189   NSMutableArray *ranges;
190
191   ranges = [NSMutableArray new];
192   selfCopy = [NSMutableString stringWithString: self];
193   [self _handleURLs: selfCopy
194         textToMatch: @"://"
195         prefix: @""
196         inRanges: ranges];
197   [self _handleURLs: selfCopy
198         textToMatch: @"@"
199         prefix: @"mailto:"
200         inRanges: ranges];
201   [ranges release];
202
203   return selfCopy;
204 }
205
206 - (NSString *) jsonRepresentation
207 {
208   NSMutableString *representation;
209
210   representation = [NSMutableString stringWithString: self];
211   [representation replaceString: @"\\" withString: @"\\\\"];
212   [representation replaceString: @"\"" withString: @"\\\""];
213   [representation replaceString: @"/" withString: @"\\/"];
214   [representation replaceString: @"\b" withString: @"\\b"];
215   [representation replaceString: @"\f" withString: @"\\f"];
216   [representation replaceString: @"\n" withString: @"\\n"];
217   [representation replaceString: @"\r" withString: @"\\r"];
218   [representation replaceString: @"\t" withString: @"\\t"];
219
220   return [NSString stringWithFormat: @"\"%@\"", representation];
221 }
222
223 #if LIB_FOUNDATION_LIBRARY
224 - (BOOL) boolValue
225 {
226   return !([self isEqualToString: @"0"]
227            || [self isEqualToString: @"NO"]);
228 }
229 #endif
230
231 @end