]> err.no Git - sope/blob - libFoundation/Foundation/NSCharacterSet.m
fixed some NGMail framework build issue
[sope] / libFoundation / Foundation / NSCharacterSet.m
1 /* 
2    NSCharacterSet.m
3
4    Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
5    All rights reserved.
6
7    Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
8
9    This file is part of libFoundation.
10
11    Permission to use, copy, modify, and distribute this software and its
12    documentation for any purpose and without fee is hereby granted, provided
13    that the above copyright notice appear in all copies and that both that
14    copyright notice and this permission notice appear in supporting
15    documentation.
16
17    We disclaim all warranties with regard to this software, including all
18    implied warranties of merchantability and fitness, in no event shall
19    we be liable for any special, indirect or consequential damages or any
20    damages whatsoever resulting from loss of use, data or profits, whether in
21    an action of contract, negligence or other tortious action, arising out of
22    or in connection with the use or performance of this software.
23 */
24
25 #include <Foundation/common.h>
26 #include <Foundation/NSCharacterSet.h>
27 #include <Foundation/NSDictionary.h>
28 #include <Foundation/NSString.h>
29 #include <Foundation/NSData.h>
30 #include <Foundation/NSCoder.h>
31 #include <Foundation/NSException.h>
32 #include <Foundation/NSLock.h>
33 #include <Foundation/NSBundle.h>
34
35 #include <Foundation/exceptions/GeneralExceptions.h>
36
37 #include "NSConcreteCharacterSet.h"
38
39 @implementation NSCharacterSet
40
41 // Cluster allocation
42
43 + (id)allocWithZone:(NSZone*)zone
44 {
45     return NSAllocateObject( (self == [NSCharacterSet class]) ? 
46         [NSBitmapCharacterSet class] : self, 0, zone);
47 }
48
49 // Creating a shared Character Set from a standard file
50 // We should mmap only ONE file and have a the sets initialized
51 // with range subdata of the main file (range subdata of NSData must
52 // not copy its data but retain its master data ...
53 // In this case we need a dictionary to know the offset of each charset
54 // in the BIG data; this approach should be very efficient on systems
55 // that support mmap (in paged virtual memory systems)
56
57 static NSMutableDictionary* predefinedCharacterSets = nil;
58
59 extern NSRecursiveLock* libFoundationLock;
60
61 + (NSCharacterSet *)characterSetWithContentsOfFile:(NSString *)fileName
62 {
63     /*
64       Note: we need to be careful here, this has potential for
65             endless recursion!
66     */
67     NSCharacterSet *aSet;
68     
69     if (fileName == nil)
70         return nil;
71     
72     [libFoundationLock lock];
73     {
74         if (predefinedCharacterSets == nil) {
75             predefinedCharacterSets =
76                 [[NSMutableDictionary alloc] initWithCapacity:12];
77         }
78         aSet = [predefinedCharacterSets objectForKey:fileName];
79     }
80     [libFoundationLock unlock];
81
82     if (aSet == nil) {
83         NSString *fullFilenamePath;
84         id data = nil;
85         
86         fullFilenamePath = [NSBundle _fileResourceNamed:fileName
87                                      extension:@"bitmap"
88                                      inDirectory:@"CharacterSets"];
89         
90         if (fullFilenamePath != nil)
91             data = [NSData dataWithContentsOfMappedFile:fullFilenamePath];
92
93         if (data == nil) {
94             /* Note: yes, this is weird, but matches Panther! */
95             data = [NSData data];
96         }
97         
98         aSet = AUTORELEASE([[NSBitmapCharacterSet alloc] 
99                                initWithBitmapRepresentation:data]);
100         if (aSet == nil) {
101             fprintf(stderr, 
102                     "ERROR(%s): could not create character set for "
103                     "data (0x%08X,len=%d) from file %s (%s)\n",
104                     __PRETTY_FUNCTION__,
105                     (unsigned int)data, [data length], [fileName cString],
106                     [fullFilenamePath cString]);
107         }
108         
109         [libFoundationLock lock];
110         [predefinedCharacterSets setObject:aSet forKey:fileName];
111         [libFoundationLock unlock];
112     }
113
114     return aSet;
115 }
116
117 // Creating a Standard Character Set 
118
119 + (NSCharacterSet*)alphanumericCharacterSet
120 {
121     return [self characterSetWithContentsOfFile:@"alphanumericCharacterSet"];
122 }
123
124 + (NSCharacterSet*)controlCharacterSet
125 {
126     return [self characterSetWithContentsOfFile:@"controlCharacterSet"];
127 }
128
129 + (NSCharacterSet*)decimalDigitCharacterSet
130 {
131     return [self characterSetWithContentsOfFile:@"decimalDigitCharacterSet"];
132 }
133
134 + (NSCharacterSet*)decomposableCharacterSet
135 {
136     return [self characterSetWithContentsOfFile:@"decomposableCharacterSet"];
137 }
138
139 + (NSCharacterSet*)illegalCharacterSet
140 {
141     return [self characterSetWithContentsOfFile:@"illegalCharacterSet"];
142 }
143
144 + (NSCharacterSet*)letterCharacterSet
145 {
146     return [self characterSetWithContentsOfFile:@"letterCharacterSet"];
147 }
148
149 + (NSCharacterSet*)lowercaseLetterCharacterSet
150 {
151     return [self characterSetWithContentsOfFile:@"lowercaseLetterCharacterSet"];
152 }
153
154 + (NSCharacterSet*)nonBaseCharacterSet
155 {
156     return [self characterSetWithContentsOfFile:@"nonBaseCharacterSet"];
157 }
158
159 + (NSCharacterSet*)uppercaseLetterCharacterSet
160 {
161     return [self characterSetWithContentsOfFile:@"uppercaseLetterCharacterSet"];
162 }
163
164 + (NSCharacterSet*)whitespaceAndNewlineCharacterSet
165 {
166     return [self characterSetWithContentsOfFile:@"whitespaceAndNewlineCharacterSet"];
167 }
168
169 + (NSCharacterSet*)whitespaceCharacterSet
170 {
171     return [self characterSetWithContentsOfFile:@"whitespaceCharacterSet"];
172 }
173
174 + (NSCharacterSet*)punctuationCharacterSet
175 {
176     return [self characterSetWithContentsOfFile:@"punctuationCharacterSet"];
177 }
178
179 + (NSCharacterSet*)emptyCharacterSet
180 {
181     return [self characterSetWithContentsOfFile:@"emptyCharacterSet"];
182 }
183
184 // Creating a Custom Character Set 
185
186 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
187 {
188     return AUTORELEASE([[NSBitmapCharacterSet alloc] 
189                            initWithBitmapRepresentation:data]);
190 }
191
192 + (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString
193 {
194     char*       bytes = CallocAtomic(1, BITMAPDATABYTES);
195     id          data;
196     int         i, count = [aString length];
197     unichar     c;
198
199     for (i = 0; i < count; i++) {
200         c = [aString characterAtIndex:i];
201         SETBIT(bytes, c);
202     }
203
204     data = [NSData dataWithBytesNoCopy:bytes 
205                    length:BITMAPDATABYTES];
206     return [self isKindOfClass:[NSMutableCharacterSet class]]
207         ? AUTORELEASE([[NSMutableBitmapCharacterSet alloc] 
208                           initWithBitmapRepresentation:data])
209         : AUTORELEASE([[NSBitmapCharacterSet alloc] 
210                           initWithBitmapRepresentation:data]);
211 }
212
213 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
214 {
215     return AUTORELEASE([[NSRangeCharacterSet alloc] initWithRange:aRange]);
216 }
217
218 // Getting a Binary Representation 
219
220 - (NSData*)bitmapRepresentation
221 {
222     [self subclassResponsibility:_cmd];
223     return nil;
224 }
225
226 // Testing Set Membership 
227
228 - (BOOL)characterIsMember:(unichar)aCharacter
229 {
230     [self subclassResponsibility:_cmd];
231     return NO;
232 }
233
234 // Inverting a Character Set 
235
236 - (NSCharacterSet*)invertedSet
237 {
238     [self subclassResponsibility:_cmd];
239     return nil;
240 }
241
242 // NSCopying
243
244 - copyWithZone:(NSZone*)zone
245 {
246     if (NSShouldRetainWithZone(self, zone))
247             return RETAIN(self);
248     else {
249             id data = [self bitmapRepresentation];
250             return [[NSCharacterSet alloc] initWithBitmapRepresentation:data];
251     }
252 }
253
254 - mutableCopyWithZone:(NSZone*)zone
255 {
256     id data = [self bitmapRepresentation];
257     return RETAIN([NSMutableCharacterSet
258                       characterSetWithBitmapRepresentation:data]);
259 }
260
261 // NSArchiving
262
263 - (Class)classForCoder
264 {
265     return [NSCharacterSet class];
266 }
267
268 - (id)replacementObjectForCoder:(NSCoder*)coder
269 {
270     if ([[self class] isKindOfClass:[NSMutableCharacterSet class]])
271         return [super replacementObjectForCoder:coder];
272     return self;
273 }
274
275 - initWithCoder:(NSCoder*)coder
276 {
277     id data;
278     id new;
279
280     [coder decodeValueOfObjCType:@encode(id) at:&data];
281     new = [[[self class] alloc] initWithBitmapRepresentation:data];
282     [self dealloc];
283     return new;
284 }
285
286 - (void)encodeWithCoder:(NSCoder*)coder
287 {
288     id data = [self bitmapRepresentation];
289     [coder encodeValueOfObjCType:@encode(id) at:&data];
290 }
291
292 @end /* NSCharacterSet */
293
294 @implementation NSMutableCharacterSet
295
296 // Cluster allocation
297
298 + (id)allocWithZone:(NSZone*)zone
299 {
300     return NSAllocateObject( (self == [NSMutableCharacterSet class]) ? 
301             [NSMutableBitmapCharacterSet class] : self, 0, zone);
302 }
303
304 // Creating a Custom Character Set 
305
306 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
307 {
308     return AUTORELEASE([[self alloc] initWithBitmapRepresentation:data]);
309 }
310
311 + (NSCharacterSet*)characterSetWithContentsOfFile:(NSString*)fileName
312 {
313     NSCharacterSet *set = [super characterSetWithContentsOfFile:fileName];
314     return AUTORELEASE([set mutableCopy]);
315 }
316 + (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString
317 {
318     NSCharacterSet *set = [super characterSetWithCharactersInString:aString];
319     return AUTORELEASE([set mutableCopy]);
320 }
321 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
322 {
323     NSCharacterSet *set = [super characterSetWithRange:aRange];
324     return AUTORELEASE([set mutableCopy]);
325 }
326
327 // Adding and Removing Characters
328
329 - (void)addCharactersInRange:(NSRange)aRange
330 {
331     [self subclassResponsibility:_cmd];
332 }
333
334 - (void)addCharactersInString:(NSString*)aString
335 {
336     [self subclassResponsibility:_cmd];
337 }
338
339 - (void)removeCharactersInRange:(NSRange)aRange
340 {
341     [self subclassResponsibility:_cmd];
342 }
343
344 - (void)removeCharactersInString:(NSString*)aString
345 {
346     [self subclassResponsibility:_cmd];
347 }
348
349 // Combining Character Sets
350
351 - (void)formIntersectionWithCharacterSet:(NSCharacterSet*)otherSet
352 {
353     [self subclassResponsibility:_cmd];
354 }
355
356 - (void)formUnionWithCharacterSet:(NSCharacterSet*)otherSet
357 {
358     [self subclassResponsibility:_cmd];
359 }
360
361 // Inverting a Character Set
362
363 - (void)invert
364 {
365     [self subclassResponsibility:_cmd];
366 }
367
368 // NSCopying
369
370 - copyWithZone:(NSZone*)zone
371 {
372     id data = [self bitmapRepresentation];
373     return RETAIN([NSCharacterSet characterSetWithBitmapRepresentation:data]);
374 }
375
376 // NSArchiving
377
378 - (Class)classForCoder
379 {
380     return [NSMutableCharacterSet class];
381 }
382
383 @end /* NSMutableCharacterSet */
384
385 /*
386   Local Variables:
387   c-basic-offset: 4
388   tab-width: 8
389   End:
390 */
391