4 Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
7 Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
9 This file is part of libFoundation.
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
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.
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>
35 #include <Foundation/exceptions/GeneralExceptions.h>
37 #include "NSConcreteCharacterSet.h"
39 @implementation NSCharacterSet
43 + (id)allocWithZone:(NSZone*)zone
45 return NSAllocateObject( (self == [NSCharacterSet class]) ?
46 [NSBitmapCharacterSet class] : (Class)self,
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)
58 static NSMutableDictionary* predefinedCharacterSets = nil;
60 extern NSRecursiveLock* libFoundationLock;
62 + (NSCharacterSet *)characterSetWithContentsOfFile:(NSString *)fileName
65 Note: we need to be careful here, this has potential for
73 [libFoundationLock lock];
75 if (predefinedCharacterSets == nil) {
76 predefinedCharacterSets =
77 [[NSMutableDictionary alloc] initWithCapacity:12];
79 aSet = [predefinedCharacterSets objectForKey:fileName];
81 [libFoundationLock unlock];
84 NSString *fullFilenamePath;
87 fullFilenamePath = [NSBundle _fileResourceNamed:fileName
89 inDirectory:@"CharacterSets"];
91 if (fullFilenamePath != nil)
92 data = [NSData dataWithContentsOfMappedFile:fullFilenamePath];
95 /* Note: yes, this is weird, but matches Panther! */
99 aSet = AUTORELEASE([[NSBitmapCharacterSet alloc]
100 initWithBitmapRepresentation:data]);
103 "ERROR(%s): could not create character set for "
104 "data (0x%p,len=%d) from file %s (%s)\n",
106 data, [data length], [fileName cString],
107 [fullFilenamePath cString]);
110 [libFoundationLock lock];
111 [predefinedCharacterSets setObject:aSet forKey:fileName];
112 [libFoundationLock unlock];
118 // Creating a Standard Character Set
120 + (NSCharacterSet*)alphanumericCharacterSet
122 return [self characterSetWithContentsOfFile:@"alphanumericCharacterSet"];
125 + (NSCharacterSet*)controlCharacterSet
127 return [self characterSetWithContentsOfFile:@"controlCharacterSet"];
130 + (NSCharacterSet*)decimalDigitCharacterSet
132 return [self characterSetWithContentsOfFile:@"decimalDigitCharacterSet"];
135 + (NSCharacterSet*)decomposableCharacterSet
137 return [self characterSetWithContentsOfFile:@"decomposableCharacterSet"];
140 + (NSCharacterSet*)illegalCharacterSet
142 return [self characterSetWithContentsOfFile:@"illegalCharacterSet"];
145 + (NSCharacterSet*)letterCharacterSet
147 return [self characterSetWithContentsOfFile:@"letterCharacterSet"];
150 + (NSCharacterSet*)lowercaseLetterCharacterSet
152 return [self characterSetWithContentsOfFile:@"lowercaseLetterCharacterSet"];
155 + (NSCharacterSet*)nonBaseCharacterSet
157 return [self characterSetWithContentsOfFile:@"nonBaseCharacterSet"];
160 + (NSCharacterSet*)uppercaseLetterCharacterSet
162 return [self characterSetWithContentsOfFile:@"uppercaseLetterCharacterSet"];
165 + (NSCharacterSet*)whitespaceAndNewlineCharacterSet
167 return [self characterSetWithContentsOfFile:@"whitespaceAndNewlineCharacterSet"];
170 + (NSCharacterSet*)whitespaceCharacterSet
172 return [self characterSetWithContentsOfFile:@"whitespaceCharacterSet"];
175 + (NSCharacterSet*)punctuationCharacterSet
177 return [self characterSetWithContentsOfFile:@"punctuationCharacterSet"];
180 + (NSCharacterSet*)emptyCharacterSet
182 return [self characterSetWithContentsOfFile:@"emptyCharacterSet"];
185 // Creating a Custom Character Set
187 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
189 return AUTORELEASE([[NSBitmapCharacterSet alloc]
190 initWithBitmapRepresentation:data]);
193 + (NSCharacterSet*)characterSetWithCharactersInString:(NSString *)aString
195 unsigned char *bytes = CallocAtomic(1, BITMAPDATABYTES);
197 unsigned int i, count;
199 for (i = 0, count = [aString length]; i < count; i++) {
202 c = [aString characterAtIndex:i];
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]);
217 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
219 return AUTORELEASE([[NSRangeCharacterSet alloc] initWithRange:aRange]);
222 // Getting a Binary Representation
224 - (NSData*)bitmapRepresentation
226 [self subclassResponsibility:_cmd];
230 // Testing Set Membership
232 - (BOOL)characterIsMember:(unichar)aCharacter
234 [self subclassResponsibility:_cmd];
238 // Inverting a Character Set
240 - (NSCharacterSet*)invertedSet
242 [self subclassResponsibility:_cmd];
248 - copyWithZone:(NSZone*)zone
250 if (NSShouldRetainWithZone(self, zone))
253 id data = [self bitmapRepresentation];
254 return [[NSCharacterSet alloc] initWithBitmapRepresentation:data];
258 - mutableCopyWithZone:(NSZone*)zone
260 id data = [self bitmapRepresentation];
261 return RETAIN([NSMutableCharacterSet
262 characterSetWithBitmapRepresentation:data]);
267 - (Class)classForCoder
269 return [NSCharacterSet class];
272 - (id)replacementObjectForCoder:(NSCoder*)coder
274 if ([[self class] isKindOfClass:[NSMutableCharacterSet class]])
275 return [super replacementObjectForCoder:coder];
279 - initWithCoder:(NSCoder*)coder
284 [coder decodeValueOfObjCType:@encode(id) at:&data];
285 new = [[[self class] alloc] initWithBitmapRepresentation:data];
290 - (void)encodeWithCoder:(NSCoder*)coder
292 id data = [self bitmapRepresentation];
293 [coder encodeValueOfObjCType:@encode(id) at:&data];
296 @end /* NSCharacterSet */
298 @implementation NSMutableCharacterSet
300 // Cluster allocation
302 + (id)allocWithZone:(NSZone*)zone
304 return NSAllocateObject( (self == [NSMutableCharacterSet class])
305 ? [NSMutableBitmapCharacterSet class]
306 : (Class)self, 0, zone);
309 // Creating a Custom Character Set
311 + (NSCharacterSet*)characterSetWithBitmapRepresentation:(NSData*)data
313 return AUTORELEASE([[self alloc] initWithBitmapRepresentation:data]);
316 + (NSCharacterSet *)characterSetWithContentsOfFile:(NSString *)fileName
318 NSCharacterSet *set = [super characterSetWithContentsOfFile:fileName];
319 return AUTORELEASE([set mutableCopy]);
321 + (NSCharacterSet *)characterSetWithCharactersInString:(NSString *)aString
323 NSCharacterSet *set = [super characterSetWithCharactersInString:aString];
324 return AUTORELEASE([set mutableCopy]);
326 + (NSCharacterSet*)characterSetWithRange:(NSRange)aRange
328 NSCharacterSet *set = [super characterSetWithRange:aRange];
329 return AUTORELEASE([set mutableCopy]);
332 // Adding and Removing Characters
334 - (void)addCharactersInRange:(NSRange)aRange
336 [self subclassResponsibility:_cmd];
339 - (void)addCharactersInString:(NSString*)aString
341 [self subclassResponsibility:_cmd];
344 - (void)removeCharactersInRange:(NSRange)aRange
346 [self subclassResponsibility:_cmd];
349 - (void)removeCharactersInString:(NSString*)aString
351 [self subclassResponsibility:_cmd];
354 // Combining Character Sets
356 - (void)formIntersectionWithCharacterSet:(NSCharacterSet*)otherSet
358 [self subclassResponsibility:_cmd];
361 - (void)formUnionWithCharacterSet:(NSCharacterSet*)otherSet
363 [self subclassResponsibility:_cmd];
366 // Inverting a Character Set
370 [self subclassResponsibility:_cmd];
375 - copyWithZone:(NSZone*)zone
377 id data = [self bitmapRepresentation];
378 return RETAIN([NSCharacterSet characterSetWithBitmapRepresentation:data]);
383 - (Class)classForCoder
385 return [NSMutableCharacterSet class];
388 @end /* NSMutableCharacterSet */