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